diff options
author | Uros Bizjak <ubizjak@gmail.com> | 2023-11-10 16:22:44 +0100 |
---|---|---|
committer | Uros Bizjak <ubizjak@gmail.com> | 2023-11-10 16:23:52 +0100 |
commit | 1ae921db2fbe0aed5860f560d52bf8920bd8e0f9 (patch) | |
tree | 3e6b04acbf7001b7b49ff2aa2ef6bfd2055b2e14 | |
parent | 99177446a22a489ccd60d374f13d8bb7237d54c2 (diff) | |
download | gcc-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.md | 74 |
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") |