diff mbox series

[committed] i386: Improve stack protector patterns and peephole2s even more

Message ID CAFULd4YZRkvfT4SOK+kQddfLL=h-wfWS=LawrgZSEV0VB3NGMw@mail.gmail.com
State New
Headers show
Series [committed] i386: Improve stack protector patterns and peephole2s even more | expand

Commit Message

Uros Bizjak Nov. 9, 2023, 6:52 p.m. UTC
Improve stack protector patterns and peephole2s even more:

a. Use unrelated register clears with integer mode size <= word
   mode size to clear stack protector scratch register.

b. Use unrelated register initializations in front of stack
   protector sequence to clear stack protector scratch register.

c. Use unrelated register initializations using LEA instructions
   to clear stack protector scratch register.

These stack protector improvements reuse 6914 unrelated register
initializations to substitute the clear of stack protector scratch
register in 12034 instances of stack protector sequence in recent linux
defconfig build.

gcc/ChangeLog:

    * config/i386/i386.md (@stack_protect_set_1_<PTR:mode>_<W:mode>):
    Use W mode iterator instead of SWI48.  Output MOV instead of XOR
    for TARGET_USE_MOV0.
    (stack_protect_set_1 peephole2): Use integer modes with
    mode size <= word mode size for operand 3.
    (stack_protect_set_1 peephole2 #2): New peephole2 pattern to
    substitute stack protector scratch register clear with unrelated
    register initialization, originally in front of stack
    protector sequence.
    (*stack_protect_set_3_<PTR:mode>_<SWI48:mode>): New insn pattern.
    (stack_protect_set_1 peephole2): New peephole2 pattern to
    substitute stack protector scratch register clear with unrelated
    register initialization involving LEA instruction.

Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.

Uros.
diff mbox series

Patch

diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index ce7102af44f..046b6b7919e 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -24306,11 +24306,11 @@  (define_expand "stack_protect_set"
   DONE;
 })
 
-(define_insn "@stack_protect_set_1_<PTR:mode>_<SWI48:mode>"
+(define_insn "@stack_protect_set_1_<PTR:mode>_<W:mode>"
   [(set (match_operand:PTR 0 "memory_operand" "=m")
 	(unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
 		    UNSPEC_SP_SET))
-   (set (match_operand:SWI48 2 "register_operand" "=&r") (const_int 0))
+   (set (match_operand:W 2 "register_operand" "=&r") (const_int 0))
    (clobber (reg:CC FLAGS_REG))]
   ""
 {
@@ -24318,7 +24318,10 @@  (define_insn "@stack_protect_set_1_<PTR:mode>_<SWI48:mode>"
 		   operands);
   output_asm_insn ("mov{<PTR:imodesuffix>}\t{%<PTR:k>2, %0|%0, %<PTR:k>2}",
 		   operands);
-  return "xor{l}\t%k2, %k2";
+  if (!TARGET_USE_MOV0 || optimize_insn_for_size_p ())
+    return "xor{l}\t%k2, %k2";
+  else
+    return "mov{l}\t{$0, %k2|%k2, 0}";
 }
   [(set_attr "type" "multi")])
 
@@ -24334,15 +24337,16 @@  (define_peephole2
 			       UNSPEC_SP_SET))
 	      (set (match_operand:W 2 "general_reg_operand") (const_int 0))
 	      (clobber (reg:CC FLAGS_REG))])
-   (parallel [(set (match_operand:SWI48 3 "general_reg_operand")
-		   (match_operand:SWI48 4 "const0_operand"))
-	      (clobber (reg:CC FLAGS_REG))])]
-  "peep2_reg_dead_p (0, operands[3])
+   (set (match_operand 3 "general_reg_operand")
+	(match_operand 4 "const0_operand"))]
+  "GET_MODE_SIZE (GET_MODE (operands[3])) <= UNITS_PER_WORD
+   && peep2_reg_dead_p (0, operands[3])
    && peep2_reg_dead_p (1, operands[2])"
   [(parallel [(set (match_dup 0)
 		   (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
 	      (set (match_dup 3) (const_int 0))
-	      (clobber (reg:CC FLAGS_REG))])])
+	      (clobber (reg:CC FLAGS_REG))])]
+  "operands[3] = gen_lowpart (word_mode, operands[3]);")
 
 (define_insn "*stack_protect_set_2_<mode>_si"
   [(set (match_operand:PTR 0 "memory_operand" "=m")
@@ -24401,6 +24405,59 @@  (define_peephole2
 		   (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
 	      (set (match_dup 3) (match_dup 4))])])
 
+(define_peephole2
+  [(set (match_operand:SWI48 3 "general_reg_operand")
+	(match_operand:SWI48 4 "general_gr_operand"))
+   (parallel [(set (match_operand:PTR 0 "memory_operand")
+		   (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
+			       UNSPEC_SP_SET))
+	      (set (match_operand:W 2 "general_reg_operand") (const_int 0))
+	      (clobber (reg:CC FLAGS_REG))])]
+  "peep2_reg_dead_p (0, operands[3])
+   && peep2_reg_dead_p (2, operands[2])
+   && !reg_mentioned_p (operands[3], operands[0])
+   && !reg_mentioned_p (operands[3], operands[1])"
+  [(parallel [(set (match_dup 0)
+		   (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
+	      (set (match_dup 3) (match_dup 4))])])
+
+(define_insn "*stack_protect_set_3_<PTR:mode>_<SWI48:mode>"
+  [(set (match_operand:PTR 0 "memory_operand" "=m")
+	(unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
+		    UNSPEC_SP_SET))
+   (set (match_operand:SWI48 1 "register_operand" "=&r")
+	(match_operand:SWI48 2 "address_no_seg_operand" "Ts"))]
+  ""
+{
+  output_asm_insn ("mov{<PTR:imodesuffix>}\t{%3, %<PTR:k>1|%<PTR:k>1, %3}",
+		   operands);
+  output_asm_insn ("mov{<PTR:imodesuffix>}\t{%<PTR:k>1, %0|%0, %<PTR:k>1}",
+		   operands);
+  if (SImode_address_operand (operands[2], VOIDmode))
+    {
+      gcc_assert (TARGET_64BIT);
+      return "lea{l}\t{%E2, %k1|%k1, %E2}";
+    }
+  else
+    return "lea{<SWI48:imodesuffix>}\t{%E2, %1|%1, %E2}";
+}
+  [(set_attr "type" "multi")
+   (set_attr "length" "24")])
+
+(define_peephole2
+  [(parallel [(set (match_operand:PTR 0 "memory_operand")
+		   (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
+			       UNSPEC_SP_SET))
+	      (set (match_operand:W 2 "general_reg_operand") (const_int 0))
+	      (clobber (reg:CC FLAGS_REG))])
+   (set (match_operand:SWI48 3 "general_reg_operand")
+	(match_operand:SWI48 4 "address_no_seg_operand"))]
+  "peep2_reg_dead_p (0, operands[3])
+   && peep2_reg_dead_p (1, operands[2])"
+  [(parallel [(set (match_dup 0)
+		   (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
+	      (set (match_dup 3) (match_dup 4))])])
+
 (define_expand "stack_protect_test"
   [(match_operand 0 "memory_operand")
    (match_operand 1 "memory_operand")