http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46399
Summary: Missing type promotion for library call argument Product: gcc Version: 4.4.3 Status: UNCONFIRMED Severity: major Priority: P3 Component: middle-end AssignedTo: unassig...@gcc.gnu.org ReportedBy: kreb...@gcc.gnu.org The following testcase produces an unexpected result when compiled with: gcc -O3 t.c -ot int main () { volatile _Decimal32 b, c; volatile unsigned int ui; volatile long long sll; ui = 1; sll = 1LL; b = sll; c = ui; printf("b: %x\n", *(int*)&b); printf("c: %x\n", *(int*)&c); } ./t: b: 22500001 c: 3a95e225 The problem appears to be a missing type promotion when doing the conversion from unsigned int to _Decimal32 in c = ui: stmg %r14,%r15,112(%r15) aghi %r15,-184 lhi %r1,1 st %r1,180(%r15) lghi %r1,1 stg %r1,160(%r15) lg %r2,160(%r15) <-- load a 64bit value into r2 brasl %r14,__dpd_floatdisd ste %f0,172(%r15) l %r2,180(%r15) <-- load a 32bit value into r2 brasl %r14,__dpd_floatunssisd without zero extending to 64bit .... When I manually kill the upper 32 bits of r2 before doing the second lib call it works fine: stmg %r14,%r15,112(%r15) aghi %r15,-184 .cfi_offset 15, -40 .cfi_offset 14, -48 .cfi_def_cfa_offset 344 lhi %r1,1 st %r1,180(%r15) lghi %r1,1 stg %r1,160(%r15) lg %r2,160(%r15) brasl %r14,__dpd_floatdisd ste %f0,172(%r15) lghi %r2,0 <-- load a 64bit 0 into r2 l %r2,180(%r15) brasl %r14,__dpd_floatunssisd ... The result then is: b: 22500001 c: 22500001 The testcase above is extracted from gcc.dg/dfp/pr41049.c which currently seems to fail due to that problem on s390*.