diff mbox series

[COMMITTED] i386: Move stack protector patterns above mov $0 -> xor peephole

Message ID CAFULd4aGkoHjPaYyCbY0wkcxVfxFR9R4uyG+=HGkdONDWJPmeA@mail.gmail.com
State New
Headers show
Series [COMMITTED] i386: Move stack protector patterns above mov $0 -> xor peephole | expand

Commit Message

Uros Bizjak Nov. 2, 2023, 10:06 a.m. UTC
Move stack protector patterns above mov $0,%reg -> xor %reg,%reg
so the latter won't interfere with stack protector peephole2s.

gcc/ChangeLog:

    * config/i386/i386.md: Move stack protector patterns
    above mov $0,%reg -> xor %reg,%reg peephole2 pattern.

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 75c75f610c2..0528b8379bf 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -24281,6 +24281,141 @@  (define_expand "restore_stack_nonlocal"
   DONE;
 })
 
+(define_expand "stack_protect_set"
+  [(match_operand 0 "memory_operand")
+   (match_operand 1 "memory_operand")]
+  ""
+{
+  rtx scratch = gen_reg_rtx (word_mode);
+
+  emit_insn (gen_stack_protect_set_1
+	     (ptr_mode, word_mode, operands[0], operands[1], scratch));
+  DONE;
+})
+
+(define_insn "@stack_protect_set_1_<PTR:mode>_<SWI48: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))
+   (clobber (reg:CC FLAGS_REG))]
+  ""
+{
+  output_asm_insn ("mov{<PTR:imodesuffix>}\t{%1, %<PTR:k>2|%<PTR:k>2, %1}",
+		   operands);
+  output_asm_insn ("mov{<PTR:imodesuffix>}\t{%<PTR:k>2, %0|%0, %<PTR:k>2}",
+		   operands);
+  return "xor{l}\t%k2, %k2";
+}
+  [(set_attr "type" "multi")])
+
+;; Patterns and peephole2s to optimize stack_protect_set_1_<mode>
+;; immediately followed by *mov{s,d}i_internal, where we can avoid
+;; the xor{l} above.  We don't split this, so that scheduling or
+;; anything else doesn't separate the *stack_protect_set* pattern from
+;; the set of the register that overwrites the register with a new value.
+
+(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))])
+   (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])
+   && 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))])])
+
+(define_insn "*stack_protect_set_2_<mode>_si"
+  [(set (match_operand:PTR 0 "memory_operand" "=m")
+	(unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
+		    UNSPEC_SP_SET))
+   (set (match_operand:SI 1 "register_operand" "=&r")
+	(match_operand:SI 2 "general_operand" "g"))]
+  "reload_completed"
+{
+  output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
+  output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
+  if (pic_32bit_operand (operands[2], SImode)
+      || ix86_use_lea_for_mov (insn, operands + 1))
+    return "lea{l}\t{%E2, %1|%1, %E2}";
+  else
+    return "mov{l}\t{%2, %1|%1, %2}";
+}
+  [(set_attr "type" "multi")
+   (set_attr "length" "24")])
+
+(define_insn "*stack_protect_set_2_<mode>_di"
+  [(set (match_operand:PTR 0 "memory_operand" "=m,m,m")
+	(unspec:PTR [(match_operand:PTR 3 "memory_operand" "m,m,m")]
+		    UNSPEC_SP_SET))
+   (set (match_operand:DI 1 "register_operand" "=&r,&r,&r")
+	(match_operand:DI 2 "general_operand" "Z,rem,i"))]
+  "TARGET_64BIT && reload_completed"
+{
+  output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
+  output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
+  if (pic_32bit_operand (operands[2], DImode))
+    return "lea{q}\t{%E2, %1|%1, %E2}";
+  else if (which_alternative == 0)
+    return "mov{l}\t{%k2, %k1|%k1, %k2}";
+  else if (which_alternative == 2)
+    return "movabs{q}\t{%2, %1|%1, %2}";
+  else if (ix86_use_lea_for_mov (insn, operands + 1))
+    return "lea{q}\t{%E2, %1|%1, %E2}";
+  else
+    return "mov{q}\t{%2, %1|%1, %2}";
+}
+  [(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 "general_gr_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")
+   (match_operand 2)]
+  ""
+{
+  rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
+
+  emit_insn (gen_stack_protect_test_1
+	     (ptr_mode, flags, operands[0], operands[1]));
+
+  emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
+				  flags, const0_rtx, operands[2]));
+  DONE;
+})
+
+(define_insn "@stack_protect_test_1_<mode>"
+  [(set (match_operand:CCZ 0 "flags_reg_operand")
+	(unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
+		     (match_operand:PTR 2 "memory_operand" "m")]
+		    UNSPEC_SP_TEST))
+   (clobber (match_scratch:PTR 3 "=&r"))]
+  ""
+{
+  output_asm_insn ("mov{<imodesuffix>}\t{%1, %3|%3, %1}", operands);
+  return "sub{<imodesuffix>}\t{%2, %3|%3, %2}";
+}
+  [(set_attr "type" "multi")])
 
 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
 ;; Do not split instructions with mask registers.
@@ -25648,142 +25783,6 @@  (define_insn "prefetchi"
 	(symbol_ref "memory_address_length (operands[0], false)"))
    (set_attr "memory" "none")])
 
-(define_expand "stack_protect_set"
-  [(match_operand 0 "memory_operand")
-   (match_operand 1 "memory_operand")]
-  ""
-{
-  rtx scratch = gen_reg_rtx (word_mode);
-
-  emit_insn (gen_stack_protect_set_1
-	     (ptr_mode, word_mode, operands[0], operands[1], scratch));
-  DONE;
-})
-
-(define_insn "@stack_protect_set_1_<PTR:mode>_<SWI48: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))
-   (clobber (reg:CC FLAGS_REG))]
-  ""
-{
-  output_asm_insn ("mov{<PTR:imodesuffix>}\t{%1, %<PTR:k>2|%<PTR:k>2, %1}",
-		   operands);
-  output_asm_insn ("mov{<PTR:imodesuffix>}\t{%<PTR:k>2, %0|%0, %<PTR:k>2}",
-		   operands);
-  return "xor{l}\t%k2, %k2";
-}
-  [(set_attr "type" "multi")])
-
-;; Patterns and peephole2s to optimize stack_protect_set_1_<mode>
-;; immediately followed by *mov{s,d}i_internal, where we can avoid
-;; the xor{l} above.  We don't split this, so that scheduling or
-;; anything else doesn't separate the *stack_protect_set* pattern from
-;; the set of the register that overwrites the register with a new value.
-
-(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))])
-   (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])
-   && 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))])])
-
-(define_insn "*stack_protect_set_2_<mode>_si"
-  [(set (match_operand:PTR 0 "memory_operand" "=m")
-	(unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
-		    UNSPEC_SP_SET))
-   (set (match_operand:SI 1 "register_operand" "=&r")
-	(match_operand:SI 2 "general_operand" "g"))]
-  "reload_completed"
-{
-  output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
-  output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
-  if (pic_32bit_operand (operands[2], SImode)
-      || ix86_use_lea_for_mov (insn, operands + 1))
-    return "lea{l}\t{%E2, %1|%1, %E2}";
-  else
-    return "mov{l}\t{%2, %1|%1, %2}";
-}
-  [(set_attr "type" "multi")
-   (set_attr "length" "24")])
-
-(define_insn "*stack_protect_set_2_<mode>_di"
-  [(set (match_operand:PTR 0 "memory_operand" "=m,m,m")
-	(unspec:PTR [(match_operand:PTR 3 "memory_operand" "m,m,m")]
-		    UNSPEC_SP_SET))
-   (set (match_operand:DI 1 "register_operand" "=&r,&r,&r")
-	(match_operand:DI 2 "general_operand" "Z,rem,i"))]
-  "TARGET_64BIT && reload_completed"
-{
-  output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
-  output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
-  if (pic_32bit_operand (operands[2], DImode))
-    return "lea{q}\t{%E2, %1|%1, %E2}";
-  else if (which_alternative == 0)
-    return "mov{l}\t{%k2, %k1|%k1, %k2}";
-  else if (which_alternative == 2)
-    return "movabs{q}\t{%2, %1|%1, %2}";
-  else if (ix86_use_lea_for_mov (insn, operands + 1))
-    return "lea{q}\t{%E2, %1|%1, %E2}";
-  else
-    return "mov{q}\t{%2, %1|%1, %2}";
-}
-  [(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 "general_gr_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")
-   (match_operand 2)]
-  ""
-{
-  rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
-
-  emit_insn (gen_stack_protect_test_1
-	     (ptr_mode, flags, operands[0], operands[1]));
-
-  emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
-				  flags, const0_rtx, operands[2]));
-  DONE;
-})
-
-(define_insn "@stack_protect_test_1_<mode>"
-  [(set (match_operand:CCZ 0 "flags_reg_operand")
-	(unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
-		     (match_operand:PTR 2 "memory_operand" "m")]
-		    UNSPEC_SP_TEST))
-   (clobber (match_scratch:PTR 3 "=&r"))]
-  ""
-{
-  output_asm_insn ("mov{<imodesuffix>}\t{%1, %3|%3, %1}", operands);
-  return "sub{<imodesuffix>}\t{%2, %3|%3, %2}";
-}
-  [(set_attr "type" "multi")])
-
 (define_insn "sse4_2_crc32<mode>"
   [(set (match_operand:SI 0 "register_operand" "=r")
 	(unspec:SI