shrink-wrap optimization produce buggy code
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
Linaro GCC |
Won't Fix
|
Medium
|
Michael Collison |
Bug Description
this issue discovered in 2011.03 but exists in 2011.04 if you enable -fshrink-wrap optimization.
for functions with variable parameters it damages r3 (last possible argument) and produce non-working code.
registers r0, r1 and r2 handled OK.
the code example produces in case valid code output
5 6 7
in case of invalid code
5 5 7
in case strings used segfault is possible.
code example
typedef __builtin_va_list __gnuc_va_list;
typedef __gnuc_va_list va_list;
extern int vprintf(char const *fmt, va_list ap);
int c;
void fun(int x, char const *y, ...) {
if (x <= c) {
va_list ap;
__builtin_
if (x > 4)
return;
vprintf(y, ap);
__builtin_
}
}
int main(void) {
c = 5;
fun(3, "%d %d %d", 5, 6, 7);
return 0;
}
correct code (with -fno-shrink-wrap)
@ args = 4, pretend = 12, frame = 8
@ frame_needed = 0, uses_anonymous_args = 1
stmfd sp!, {r1, r2, r3} <- r3 saved
.save {r1, r2, r3}
.....
incorrect code (-fshrink-wrap)
@ args = 4, pretend = 12, frame = 8
@ frame_needed = 0, uses_anonymous_args = 1
movw r3, #:lower16:c <- :(
movt r3, #:upper16:c <- :(
ldr r3, [r3, #0] <- :(
cmp r3, r0
bxlt lr
stmfd sp!, {r1, r2, r3}
Btw, mainline gcc 4.5 do not have this problem. gcc 4.4 do not have such optimization.