On Thu, Jun 16, 2016 at 11:51:12AM +0200, Jakub Jelinek wrote: > Here is what I've committed to the trunk and 6.2 after bootstrap/regtest on > x86_64-linux and i686-linux. > For 5/4.9, this doesn't apply cleanly, as http://gcc.gnu.org/r222592 > aka https://gcc.gnu.org/ml/gcc-patches/2015-04/msg01930.html > has not been backported. Shall I backport that too, or just not apply to > 5/4.9? I guess I should, because: > int v; > __attribute__ ((noinline, noclone)) void bar (void) { v++; } > __attribute__ ((noinline, noclone)) void foo (unsigned int x) { signed int y > = ((-__INT_MAX__ - 1) / 2), r; if (__builtin_mul_overflow (x, y, &r)) bar (); > } > int main () { foo (2); if (v) __builtin_abort (); return 0; } > is miscompiled with -m32 -O2 in 5.x (though, 4.9 doesn't support > __builtin_*_overflow, so maybe it is not an issue there).
Ok, I went ahead and committed following to 5.x branch and the testcase also to trunk and 6.2. What is your preference for 4.9? The testcase isn't applicable. 2016-06-16 Jakub Jelinek <ja...@redhat.com> PR target/71554 * config/i386/i386.md (setcc + movzbl peephole2): Use reg_set_p. (setcc + and peephole2): Likewise. Backported from mainline 2015-04-29 Uros Bizjak <ubiz...@gmail.com> * config/i386/i386.md (setcc+movzbl peephole2): Check also clobbered reg. (setcc+andl peephole2): Ditto. 2016-06-16 Jakub Jelinek <ja...@redhat.com> PR target/71554 * gcc.c-torture/execute/pr71554.c: New test. --- gcc/config/i386/i386.md (revision 237518) +++ gcc/config/i386/i386.md (working copy) @@ -11645,7 +11645,8 @@ (define_peephole2 (zero_extend (match_dup 1)))] "(peep2_reg_dead_p (3, operands[1]) || operands_match_p (operands[1], operands[3])) - && ! reg_overlap_mentioned_p (operands[3], operands[0])" + && ! reg_overlap_mentioned_p (operands[3], operands[0]) + && ! reg_set_p (operands[3], operands[4])" [(parallel [(set (match_dup 5) (match_dup 0)) (match_dup 4)]) (set (strict_low_part (match_dup 6)) @@ -11688,7 +11689,8 @@ (define_peephole2 (clobber (reg:CC FLAGS_REG))])] "(peep2_reg_dead_p (3, operands[1]) || operands_match_p (operands[1], operands[3])) - && ! reg_overlap_mentioned_p (operands[3], operands[0])" + && ! reg_overlap_mentioned_p (operands[3], operands[0]) + && ! reg_set_p (operands[3], operands[4])" [(parallel [(set (match_dup 5) (match_dup 0)) (match_dup 4)]) (set (strict_low_part (match_dup 6)) --- gcc/testsuite/gcc.c-torture/execute/pr71554.c (revision 0) +++ gcc/testsuite/gcc.c-torture/execute/pr71554.c (working copy) @@ -0,0 +1,28 @@ +/* PR target/71554 */ + +int v; + +__attribute__ ((noinline, noclone)) void +bar (void) +{ + v++; +} + +__attribute__ ((noinline, noclone)) +void +foo (unsigned int x) +{ + signed int y = ((-__INT_MAX__ - 1) / 2); + signed int r; + if (__builtin_mul_overflow (x, y, &r)) + bar (); +} + +int +main () +{ + foo (2); + if (v) + __builtin_abort (); + return 0; +} Jakub