Consider: extern void bar (int);
foo (int *array) { int i; for (i = 0; i <= 10; i++) { bar (i + 1); array[i / ((unsigned) 32)] |= ((unsigned long) 1) << (i % ((unsigned) (32))); } } The last tree SSA dump looks like so: foo (array) { unsigned int D.1154; unsigned int D.1152; unsigned int D.1153; unsigned int ivtmp.5; int pretmp.4; unsigned int pretmp.3; int pretmp.2; int i; int D.1136; long unsigned int D.1135; long unsigned int D.1134; int D.1133; long unsigned int D.1132; int D.1131; int * D.1130; int * D.1129; unsigned int D.1128; unsigned int D.1127; unsigned int i.0; int D.1125; <bb 0>: # i_24 = PHI <i_1(1), 0(0)>; <L0>:; D.1152_7 = (unsigned int) i_24; D.1153_20 = D.1152_7 + 1; i_1 = (int) D.1153_20; bar (i_1); D.1154_27 = (unsigned int) i_1; i.0_28 = D.1154_27 + 0ffffffff; D.1127_5 = i.0_28 >> 5; D.1128_10 = D.1127_5 * 4; D.1129_11 = (int *) D.1128_10; D.1130_12 = array_8 + D.1129_11; D.1131_13 = *D.1130_12; D.1132_14 = (long unsigned int) D.1131_13; D.1133_15 = i_24 & 31; D.1134_16 = 1 << D.1133_15; D.1135_17 = D.1132_14 | D.1134_16; D.1136_18 = (int) D.1135_17; *D.1130_12 = D.1136_18; if (D.1153_20 != 11) goto <L0>; else goto <L2>; <L2>:; return; } Note that D.1152_7 == i.0_28, but this equality is not noticed at tree level due to signedness changes in between. We should replace the definition of i.0_28 as i.0_28 = D.1152_7; and the copy propagation should take care of the rest. The rtl optimizers catch this opportunity. -- Summary: equality not noticed when signedness differs. Product: gcc Version: unknown Status: UNCONFIRMED Keywords: missed-optimization, TREE Severity: enhancement Priority: P2 Component: tree-optimization AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: kazu at cs dot umass dot edu CC: gcc-bugs at gcc dot gnu dot org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19790