Skip to content

Commit

Permalink
i386: Improve stack protector patterns and peephole2s even more
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
ubizjak committed Nov 9, 2023
1 parent a99f6bb commit 016b300
Showing 1 changed file with 66 additions and 9 deletions.
75 changes: 66 additions & 9 deletions gcc/config/i386/i386.md
Original file line number Diff line number Diff line change
Expand Up @@ -6172,7 +6172,7 @@
gcc_assert (TARGET_64BIT);
return "lea{l}\t{%E1, %k0|%k0, %E1}";
}
else
else
return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
}
[(set_attr "type" "lea")
Expand Down Expand Up @@ -24306,19 +24306,22 @@
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))]
""
{
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";
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")])

Expand All @@ -24334,15 +24337,16 @@
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")
Expand Down Expand Up @@ -24401,6 +24405,59 @@
(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")
Expand Down

0 comments on commit 016b300

Please sign in to comment.