In attached code: in find(), generated code computes offset using multiplication/division. in set(), generated code computes &data[10] and compares &data[i] with that (to verify find() fails to be optimised because of overflow rules)
tested gcc: 4.3.4, 4.4.1, 4.5.0-alpha20090827 command line: gcc main.c -o main.o -c -O3 -f(no-)strict-overflow or -m32 doesn't have any effect on that behaviour --------------------------------- static struct { int a, b, c; char pad[200]; /* padding so offset computation has to use expensive div/mul */ } data[1000]; /* 1000 so loop isn't unrolled */ int find(int val) { int i; for (i = 0; i < 1000; i++) { if (data[i].a == val) return &data[i] - data; /* does *212, /212 */ } return -1; } void set(int val) { int i; for (i = 0; i < 1000; i++) { data[i].b = &data[i] - data < 10 || data[i].a == val; /* compares with &data[10] */ } } --------------------------------- Relevant generated ASM: (eax is "i", sar+imul is converted division by 212) --------------------------------- cdqe imul rax, rax, 212 sar rax, 2 imul eax, eax, -1944890851 ret --------------------------------- -- Summary: "&data[i] - data" isn't converted to "i" Product: gcc Version: 4.5.0 Status: UNCONFIRMED Severity: enhancement Priority: P3 Component: tree-optimization AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: zsojka at seznam dot cz GCC host triplet: x86_64-pc-linux-gnu http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41244