aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUros Bizjak <ubizjak@gmail.com>2023-11-10 16:22:44 +0100
committerUros Bizjak <ubizjak@gmail.com>2023-11-10 16:23:52 +0100
commit1ae921db2fbe0aed5860f560d52bf8920bd8e0f9 (patch)
tree3e6b04acbf7001b7b49ff2aa2ef6bfd2055b2e14
parent99177446a22a489ccd60d374f13d8bb7237d54c2 (diff)
downloadgcc-1ae921db2fbe0aed5860f560d52bf8920bd8e0f9.zip
gcc-1ae921db2fbe0aed5860f560d52bf8920bd8e0f9.tar.gz
gcc-1ae921db2fbe0aed5860f560d52bf8920bd8e0f9.tar.bz2
i386: Clear stack protector scratch with zero/sign-extend instruction
Use unrelated register initializations using zero/sign-extend instructions to clear stack protector scratch register. Hanlde only SI -> DImode extensions for 64-bit targets, as this is the only extension that triggers the peephole in a non-negligible number. Also use explicit check for word_mode instead of mode iterator in peephole2 patterns to avoid pattern explosion. gcc/ChangeLog: * config/i386/i386.md (stack_protect_set_1 peephole2): Explicitly check operand 2 for word_mode. (stack_protect_set_1 peephole2 #2): Ditto. (stack_protect_set_2 peephole2): Ditto. (stack_protect_set_3 peephole2): Ditto. (*stack_protect_set_4z_<mode>_di): New insn patter. (*stack_protect_set_4s_<mode>_di): Ditto. (stack_protect_set_4 peephole2): New peephole2 pattern to substitute stack protector scratch register clear with unrelated register initialization involving zero/sign-extend instruction.
-rw-r--r--gcc/config/i386/i386.md74
1 files changed, 66 insertions, 8 deletions
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 9dc614c..01fc6ec 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -24335,11 +24335,12 @@
[(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))
+ (set (match_operand 2 "general_reg_operand") (const_int 0))
(clobber (reg:CC FLAGS_REG))])
(set (match_operand 3 "general_reg_operand")
(match_operand 4 "const0_operand"))]
- "GET_MODE_SIZE (GET_MODE (operands[3])) <= UNITS_PER_WORD
+ "GET_MODE (operands[2]) == word_mode
+ && 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)
@@ -24395,11 +24396,12 @@
[(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))
+ (set (match_operand 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])
+ "GET_MODE (operands[2]) == word_mode
+ && 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))
@@ -24411,9 +24413,10 @@
(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))
+ (set (match_operand 2 "general_reg_operand") (const_int 0))
(clobber (reg:CC FLAGS_REG))])]
- "peep2_reg_dead_p (0, operands[3])
+ "GET_MODE (operands[2]) == word_mode
+ && 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])"
@@ -24448,16 +24451,71 @@
[(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))
+ (set (match_operand 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])
+ "GET_MODE (operands[2]) == word_mode
+ && 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_insn "*stack_protect_set_4z_<mode>_di"
+ [(set (match_operand:PTR 0 "memory_operand" "=m")
+ (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
+ UNSPEC_SP_SET))
+ (set (match_operand:DI 1 "register_operand" "=&r")
+ (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))]
+ "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 (ix86_use_lea_for_mov (insn, operands + 1))
+ return "lea{l}\t{%E2, %k1|%k1, %E2}";
+ else
+ return "mov{l}\t{%2, %k1|%k1, %2}";
+}
+ [(set_attr "type" "multi")
+ (set_attr "length" "24")])
+
+(define_insn "*stack_protect_set_4s_<mode>_di"
+ [(set (match_operand:PTR 0 "memory_operand" "=m,m")
+ (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m,m")]
+ UNSPEC_SP_SET))
+ (set (match_operand:DI 1 "register_operand" "=&a,&r")
+ (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "0,rm")))]
+ "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 (which_alternative)
+ return "movs{lq|x}\t{%2, %1|%1, %2}";
+ else
+ return "{cltq|cdqe}";
+}
+ [(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 2 "general_reg_operand") (const_int 0))
+ (clobber (reg:CC FLAGS_REG))])
+ (set (match_operand:DI 3 "general_reg_operand")
+ (any_extend:DI
+ (match_operand:SI 4 "nonimmediate_gr_operand")))]
+ "TARGET_64BIT
+ && GET_MODE (operands[2]) == word_mode
+ && 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)
+ (any_extend:DI (match_dup 4)))])])
+
(define_expand "stack_protect_test"
[(match_operand 0 "memory_operand")
(match_operand 1 "memory_operand")