From: Jakub Jelinek Date: Fri, 13 Oct 2017 07:29:51 +0000 (+0200) Subject: re PR target/82524 (expensive-optimizations produces wrong results) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=5752d1f7943db65667edeaf8481dc10b60a23197;p=gcc.git 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, *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, *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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b8346e3827e..cb9f1a392aa 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,14 @@ 2017-10-13 Jakub Jelinek + PR target/82524 + * config/i386/i386.md (addqi_ext_1, andqi_ext_1, + *andqi_ext_1_cc, *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, *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) : 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 2fa982c3b65..3413b90028f 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -6264,7 +6264,7 @@ (set_attr "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" "")]) (define_insn "*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])" "{b}\t{%2, %h0|%h0, %2}" [(set_attr "isa" "*,nox64") (set_attr "type" "alu") (set_attr "mode" "QI")]) (define_insn "*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]))" "{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 ff6d7438956..566864c2183 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2017-10-13 Jakub Jelinek + 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 00000000000..07ac4b61916 --- /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; +}