From 7c32b0d5ccd3dcd0358f4fa2207713754b768649 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 17 Dec 2019 21:40:01 +0100 Subject: [PATCH] re PR target/92841 (Optimize -fstack-protector-strong code generation a bit) PR target/92841 * config/i386/i386.md (@stack_protect_set_1_, @stack_protect_test_1_): Use output_asm_insn. (*stack_protect_set_2_, *stack_protect_set_3): New define_insns and corresponding define_peephole2s. * gcc.target/i386/pr92841.c: New test. From-SVN: r279468 --- gcc/ChangeLog | 8 +++ gcc/config/i386/i386.md | 102 +++++++++++++++++++++++++++++++- gcc/testsuite/ChangeLog | 5 ++ gcc/testsuite/gcc.target/i386/pr92841.c | 17 ++++++ 4 files changed, 130 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr92841.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e5702ae..6267594 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2019-12-17 Jakub Jelinek + + PR target/92841 + * config/i386/i386.md (@stack_protect_set_1_, + @stack_protect_test_1_): Use output_asm_insn. + (*stack_protect_set_2_, *stack_protect_set_3): New define_insns + and corresponding define_peephole2s. + 2019-12-17 Jan Hubicka * symtab.c (symtab_node::get_partitioning_class): Aliases of external diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index cf4a0cc..672fd1c 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -19768,9 +19768,104 @@ (set (match_scratch:PTR 2 "=&r") (const_int 0)) (clobber (reg:CC FLAGS_REG))] "" - "mov{}\t{%1, %2|%2, %1}\;mov{}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2" +{ + output_asm_insn ("mov{}\t{%1, %2|%2, %1}", operands); + output_asm_insn ("mov{}\t{%2, %0|%0, %2}", operands); + return "xor{l}\t%k2, %k2"; +} [(set_attr "type" "multi")]) +;; Patterns and peephole2s to optimize stack_protect_set_1_ +;; immediately followed by *mov{s,d}i_internal to the same register, +;; 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_insn "*stack_protect_set_2_" + [(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")) + (clobber (reg:CC FLAGS_REG))] + "reload_completed + && !reg_overlap_mentioned_p (operands[1], operands[2])" +{ + output_asm_insn ("mov{}\t{%3, %1|%1, %3}", operands); + output_asm_insn ("mov{}\t{%1, %0|%0, %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_peephole2 + [(parallel [(set (match_operand:PTR 0 "memory_operand") + (unspec:PTR [(match_operand:PTR 1 "memory_operand")] + UNSPEC_SP_SET)) + (set (match_operand:PTR 2 "general_reg_operand") (const_int 0)) + (clobber (reg:CC FLAGS_REG))]) + (set (match_operand:SI 3 "general_reg_operand") + (match_operand:SI 4))] + "REGNO (operands[2]) == REGNO (operands[3]) + && (general_reg_operand (operands[4], SImode) + || memory_operand (operands[4], SImode) + || immediate_operand (operands[4], SImode)) + && !reg_overlap_mentioned_p (operands[3], operands[4])" + [(parallel [(set (match_dup 0) + (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET)) + (set (match_dup 3) (match_dup 4)) + (clobber (reg:CC FLAGS_REG))])]) + +(define_insn "*stack_protect_set_3" + [(set (match_operand:DI 0 "memory_operand" "=m,m,m") + (unspec:DI [(match_operand:DI 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")) + (clobber (reg:CC FLAGS_REG))] + "TARGET_64BIT + && reload_completed + && !reg_overlap_mentioned_p (operands[1], operands[2])" +{ + output_asm_insn ("mov{q}\t{%3, %1|%1, %3}", operands); + output_asm_insn ("mov{q}\t{%1, %0|%0, %1}", operands); + 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 (pic_32bit_operand (operands[2], DImode) + || 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:DI 0 "memory_operand") + (unspec:DI [(match_operand:DI 1 "memory_operand")] + UNSPEC_SP_SET)) + (set (match_operand:DI 2 "general_reg_operand") (const_int 0)) + (clobber (reg:CC FLAGS_REG))]) + (set (match_dup 2) (match_operand:DI 3))] + "TARGET_64BIT + && (general_reg_operand (operands[3], DImode) + || memory_operand (operands[3], DImode) + || x86_64_zext_immediate_operand (operands[3], DImode) + || x86_64_immediate_operand (operands[3], DImode) + || (CONSTANT_P (operands[3]) + && (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[3])))) + && !reg_overlap_mentioned_p (operands[2], operands[3])" + [(parallel [(set (match_dup 0) + (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET)) + (set (match_dup 2) (match_dup 3)) + (clobber (reg:CC FLAGS_REG))])]) + (define_expand "stack_protect_test" [(match_operand 0 "memory_operand") (match_operand 1 "memory_operand") @@ -19794,7 +19889,10 @@ UNSPEC_SP_TEST)) (clobber (match_scratch:PTR 3 "=&r"))] "" - "mov{}\t{%1, %3|%3, %1}\;sub{}\t{%2, %3|%3, %2}" +{ + output_asm_insn ("mov{}\t{%1, %3|%3, %1}", operands); + return "sub{}\t{%2, %3|%3, %2}"; +} [(set_attr "type" "multi")]) (define_insn "sse4_2_crc32" diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3794eba..0ba27eb 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-12-17 Jakub Jelinek + + PR target/92841 + * gcc.target/i386/pr92841.c: New test. + 2019-12-17 Christophe Lyon * gcc.target/arm/pr45701-1.c: Adjust for -mpure-code. diff --git a/gcc/testsuite/gcc.target/i386/pr92841.c b/gcc/testsuite/gcc.target/i386/pr92841.c new file mode 100644 index 0000000..30be2b6 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr92841.c @@ -0,0 +1,17 @@ +/* PR target/92841 */ +/* { dg-do compile { target fstack_protector } } */ +/* { dg-options "-O2 -fstack-protector-strong -masm=att" } */ +/* { dg-final { scan-assembler-not "xor\[lq]\t%(\[re]\[a-z0-9]*), %\\1\[\n\r]*\tmov\[lq]\t\[^\n\r]*, %\\1" } } */ + +const struct S { int b; } c[] = {30, 12, 20, 0, 11}; +void bar (int *); + +void +foo (void) +{ + int e[4]; + const struct S *a; + for (a = c; a < c + sizeof (c) / sizeof (c[0]); a++) + if (a->b) + bar (e); +} -- 2.7.4