diff options
author | Jakub Jelinek <jakub@redhat.com> | 2017-10-13 09:29:51 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2017-10-13 09:29:51 +0200 |
commit | 5752d1f7943db65667edeaf8481dc10b60a23197 (patch) | |
tree | 34ada7dd92163360dda28ca0bfa8dbae0ab5c47a /gcc | |
parent | a0e4174cd80f8a17026d6c13af2802dc8a0146ad (diff) | |
download | gcc-5752d1f7943db65667edeaf8481dc10b60a23197.zip gcc-5752d1f7943db65667edeaf8481dc10b60a23197.tar.gz gcc-5752d1f7943db65667edeaf8481dc10b60a23197.tar.bz2 |
re PR target/82524 (expensive-optimizations produces wrong results)
PR target/82524
* config/i386/i386.md (addqi_ext_1, andqi_ext_1,
*andqi_ext_1_cc, *<code>qi_ext_1, *xorqi_ext_1_cc): Change
=Q constraints to +Q and into insn condition add check
that operands[0] and operands[1] are equal.
(*addqi_ext_2, *andqi_ext_2, *<code>qi_ext_2): Change
=Q constraints to +Q and into insn condition add check
that operands[0] is equal to either operands[1] or operands[2].
* gcc.c-torture/execute/pr82524.c: New test.
From-SVN: r253710
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/config/i386/i386.md | 47 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/pr82524.c | 37 |
4 files changed, 80 insertions, 16 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b8346e3..cb9f1a3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,14 @@ 2017-10-13 Jakub Jelinek <jakub@redhat.com> + PR target/82524 + * config/i386/i386.md (addqi_ext_1, andqi_ext_1, + *andqi_ext_1_cc, *<code>qi_ext_1, *xorqi_ext_1_cc): Change + =Q constraints to +Q and into insn condition add check + that operands[0] and operands[1] are equal. + (*addqi_ext_2, *andqi_ext_2, *<code>qi_ext_2): Change + =Q constraints to +Q and into insn condition add check + that operands[0] is equal to either operands[1] or operands[2]. + PR target/82498 * fold-const.c (fold_binary_loc) <bit_rotate>: Code cleanups, instead of handling MINUS_EXPR twice (once for each argument), diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 2fa982c..3413b90 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -6264,7 +6264,7 @@ (set_attr "mode" "<MODE>")]) (define_insn "addqi_ext_1" - [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q") + [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q") (const_int 8) (const_int 8)) (subreg:SI @@ -6275,7 +6275,8 @@ (const_int 8)) 0) (match_operand:QI 2 "general_operand" "QnBc,m")) 0)) (clobber (reg:CC FLAGS_REG))] - "" + "/* FIXME: without this LRA can't reload this pattern, see PR82524. */ + rtx_equal_p (operands[0], operands[1])" { switch (get_attr_type (insn)) { @@ -6300,7 +6301,7 @@ (set_attr "mode" "QI")]) (define_insn "*addqi_ext_2" - [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") + [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q") (const_int 8) (const_int 8)) (subreg:SI @@ -6314,7 +6315,9 @@ (const_int 8) (const_int 8)) 0)) 0)) (clobber (reg:CC FLAGS_REG))] - "" + "/* FIXME: without this LRA can't reload this pattern, see PR82524. */ + rtx_equal_p (operands[0], operands[1]) + || rtx_equal_p (operands[0], operands[2])" "add{b}\t{%h2, %h0|%h0, %h2}" [(set_attr "type" "alu") (set_attr "mode" "QI")]) @@ -8998,7 +9001,7 @@ (set_attr "mode" "QI")]) (define_insn "andqi_ext_1" - [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q") + [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q") (const_int 8) (const_int 8)) (subreg:SI @@ -9009,7 +9012,8 @@ (const_int 8)) 0) (match_operand:QI 2 "general_operand" "QnBc,m")) 0)) (clobber (reg:CC FLAGS_REG))] - "" + "/* FIXME: without this LRA can't reload this pattern, see PR82524. */ + rtx_equal_p (operands[0], operands[1])" "and{b}\t{%2, %h0|%h0, %2}" [(set_attr "isa" "*,nox64") (set_attr "type" "alu") @@ -9027,7 +9031,7 @@ (const_int 8)) 0) (match_operand:QI 2 "general_operand" "QnBc,m")) (const_int 0))) - (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q") + (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q") (const_int 8) (const_int 8)) (subreg:SI @@ -9037,14 +9041,16 @@ (const_int 8) (const_int 8)) 0) (match_dup 2)) 0))] - "ix86_match_ccmode (insn, CCNOmode)" + "ix86_match_ccmode (insn, CCNOmode) + /* FIXME: without this LRA can't reload this pattern, see PR82524. */ + && rtx_equal_p (operands[0], operands[1])" "and{b}\t{%2, %h0|%h0, %2}" [(set_attr "isa" "*,nox64") (set_attr "type" "alu") (set_attr "mode" "QI")]) (define_insn "*andqi_ext_2" - [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") + [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q") (const_int 8) (const_int 8)) (subreg:SI @@ -9058,7 +9064,9 @@ (const_int 8) (const_int 8)) 0)) 0)) (clobber (reg:CC FLAGS_REG))] - "" + "/* FIXME: without this LRA can't reload this pattern, see PR82524. */ + rtx_equal_p (operands[0], operands[1]) + || rtx_equal_p (operands[0], operands[2])" "and{b}\t{%h2, %h0|%h0, %h2}" [(set_attr "type" "alu") (set_attr "mode" "QI")]) @@ -9431,7 +9439,7 @@ (set_attr "mode" "<MODE>")]) (define_insn "*<code>qi_ext_1" - [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q") + [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q") (const_int 8) (const_int 8)) (subreg:SI @@ -9442,14 +9450,16 @@ (const_int 8)) 0) (match_operand:QI 2 "general_operand" "QnBc,m")) 0)) (clobber (reg:CC FLAGS_REG))] - "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)" + "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) + /* FIXME: without this LRA can't reload this pattern, see PR82524. */ + && rtx_equal_p (operands[0], operands[1])" "<logic>{b}\t{%2, %h0|%h0, %2}" [(set_attr "isa" "*,nox64") (set_attr "type" "alu") (set_attr "mode" "QI")]) (define_insn "*<code>qi_ext_2" - [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") + [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q") (const_int 8) (const_int 8)) (subreg:SI @@ -9463,7 +9473,10 @@ (const_int 8) (const_int 8)) 0)) 0)) (clobber (reg:CC FLAGS_REG))] - "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)" + "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) + /* FIXME: without this LRA can't reload this pattern, see PR82524. */ + && (rtx_equal_p (operands[0], operands[1]) + || rtx_equal_p (operands[0], operands[2]))" "<logic>{b}\t{%h2, %h0|%h0, %h2}" [(set_attr "type" "alu") (set_attr "mode" "QI")]) @@ -9552,7 +9565,7 @@ (const_int 8)) 0) (match_operand:QI 2 "general_operand" "QnBc,m")) (const_int 0))) - (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q") + (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q") (const_int 8) (const_int 8)) (subreg:SI @@ -9562,7 +9575,9 @@ (const_int 8) (const_int 8)) 0) (match_dup 2)) 0))] - "ix86_match_ccmode (insn, CCNOmode)" + "ix86_match_ccmode (insn, CCNOmode) + /* FIXME: without this LRA can't reload this pattern, see PR82524. */ + && rtx_equal_p (operands[0], operands[1])" "xor{b}\t{%2, %h0|%h0, %2}" [(set_attr "isa" "*,nox64") (set_attr "type" "alu") diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ff6d743..566864c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2017-10-13 Jakub Jelinek <jakub@redhat.com> + PR target/82524 + * gcc.c-torture/execute/pr82524.c: New test. + PR target/82498 * gcc.dg/tree-ssa/pr82498.c: New test. diff --git a/gcc/testsuite/gcc.c-torture/execute/pr82524.c b/gcc/testsuite/gcc.c-torture/execute/pr82524.c new file mode 100644 index 0000000..07ac4b6 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr82524.c @@ -0,0 +1,37 @@ +/* PR target/82524 */ + +struct S { unsigned char b, g, r, a; }; +union U { struct S c; unsigned v; }; + +static inline unsigned char +foo (unsigned char a, unsigned char b) +{ + return ((a + 1) * b) >> 8; +} + +__attribute__((noinline, noclone)) unsigned +bar (union U *x, union U *y) +{ + union U z; + unsigned char v = x->c.a; + unsigned char w = foo (y->c.a, 255 - v); + z.c.r = foo (x->c.r, v) + foo (y->c.r, w); + z.c.g = foo (x->c.g, v) + foo (y->c.g, w); + z.c.b = foo (x->c.b, v) + foo (y->c.b, w); + z.c.a = 0; + return z.v; +} + +int +main () +{ + union U a, b, c; + if ((unsigned char) ~0 != 255 || sizeof (unsigned) != 4) + return 0; + a.c = (struct S) { 255, 255, 255, 0 }; + b.c = (struct S) { 255, 255, 255, 255 }; + c.v = bar (&a, &b); + if (c.c.b != 255 || c.c.g != 255 || c.c.r != 255 || c.c.a != 0) + __builtin_abort (); + return 0; +} |