uint convert_uint_sat_rte(float x);int main() { float x1; x1 = 9223373136366403584.000000f;
uint r1 = convert_uint_sat_rte(x1);
printf("%x\n", r1);
}
uint convert_uint_sat_rte(float x)
{
return bigger(x) ? 0xffffffff: (small(x) ? 0 : rintf(x));
}
clang 3.6 + O2 get blow IR
define i32 @convert_uint_sat_rte(float %x) #0 {
entry:
%call = call fastcc i32 @bigger(float %x)
%tobool = icmp ne i32 %call, 0
br i1 %tobool, label %cond.end6, label %cond.false
cond.false: ; preds = %entry
%call1 = call fastcc i32 @small(float %x)
%tobool2 = icmp ne i32 %call1, 0
br i1 %tobool2, label %cond.end6, label %cond.false4
cond.false4: ; preds = %cond.false
%call5 = call fastcc float @mce_rintf(float %x)
br label %cond.end6
cond.end6: ; preds = %cond.false4, %cond.false, %entry
%cond7 = phi float [ 0x41F0000000000000, %entry ], [ %call5, %cond.false4 ], [ 0.000000e+00, %cond.false ]
%conv = fptoui float %cond7 to i32
ret i32 %conv
}
instructionCommbing will optimize phi instruction as below
cond.end6: ; preds = %cond.false4, %cond.false, %entry
%cond7 = phi float [ fptoui(0x41F0000000000000), %entry ], [fptoui (call5), %cond.false4 ], [fptoui(0.000000e+00, %cond.false ]
ret i32 %cond7
%cond7 = phi i32 [ undef, %entry ], [ %phitmp, %mce_rintf.exit ], [ 0, %cond.false ]
undef will generate failed code,
3.5 is fine because without this patch
in C99, float 's rank is > any integer, so in this case
return bigger(x) ? 0xffffffff: (small(x) ? 0 : rintf(x));rewrite as blow code will got correct result with O2 ( but it's strange O0 can get correct result)
return bigger(x) ? 0xffffffff: (small(x) ? 0 : (uint) rintf(x));
沒有留言:
張貼留言