Compiling the following with -O results in a function that always returns zero, instead of one that always returns 1. int foo (int a, unsigned int x) { unsigned int n = 0; while (a) x = x + 1, a = a << 1; return x >= n; }
Fixing
Patch here: http://gcc.gnu.org/ml/gcc-patches/2004-03/msg00696.html
This is fixed on the tree-ssa because of constant propagation.
Could you perhaps tickle the bug on tree-ssa with a different testcase? Note that on mainline, the problem insns are generated by combine.
You almost cannot as it will constant fold "unsigned >= 0" always before even getting to the RTL.
Subject: Bug 14478 CVSROOT: /cvs/gcc Module name: gcc Branch: hammer-3_3-branch Changes by: amodra@gcc.gnu.org 2004-03-09 13:39:41 Modified files: gcc : ChangeLog.hammer gcc/config/rs6000: rs6000.md Log message: PR target/14478 * config/rs6000/rs6000.md: Give all reg_or_neg_short_operand constraints a zero alternative. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.hammer.diff?cvsroot=gcc&only_with_tag=hammer-3_3-branch&r1=1.1.2.371&r2=1.1.2.372 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/config/rs6000/rs6000.md.diff?cvsroot=gcc&only_with_tag=hammer-3_3-branch&r1=1.221.4.16&r2=1.221.4.17
Newest patch to reject the RTL patterns from being made in the first place: <http://gcc.gnu.org/ml/ gcc-patches/2004-05/msg01669.html>
Subject: Bug 14478 CVSROOT: /cvs/gcc Module name: gcc Changes by: amodra@gcc.gnu.org 2004-05-27 07:41:53 Modified files: gcc : ChangeLog gcc/config/rs6000: rs6000.c Log message: PR target/14478 * config/rs6000/rs6000.c (reg_or_neg_short_operand): Don't allow zero. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&r1=2.3760&r2=2.3761 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/config/rs6000/rs6000.c.diff?cvsroot=gcc&r1=1.645&r2=1.646
Subject: Bug 14478 CVSROOT: /cvs/gcc Module name: gcc Branch: gcc-3_4-branch Changes by: amodra@gcc.gnu.org 2004-05-27 07:42:29 Modified files: gcc : ChangeLog gcc/config/rs6000: rs6000.c Log message: PR target/14478 * config/rs6000/rs6000.c (reg_or_neg_short_operand): Don't allow zero. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=2.2326.2.450&r2=2.2326.2.451 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/config/rs6000/rs6000.c.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.576.2.19&r2=1.576.2.20
Fixed on 3.4 and head.