The instruction combiner is making the following transformation: %tmp = load int* %tmp1 ; <int> [#uses=1] %tmp = cast int %tmp to uint ; <uint> [#uses=1] - %tmp2 = shr uint %tmp, ubyte 5 ; <uint> [#uses=1] - %tmp2 = cast uint %tmp2 to int ; <int> [#uses=1] - %tmp3 = and int %tmp2, 1 ; <int> [#uses=1] - %tmp3 = cast int %tmp3 to bool ; <bool> [#uses=1] - %tmp34 = cast bool %tmp3 to int ; <int> [#uses=1] + %tmp3 = setgt uint %tmp, 31 ; <bool> [#uses=1] + %tmp34 = cast bool %tmp3 to int ; <int> [#uses=2] simplifying "(x >> 5) & 1 != 0" into "x > 31". They are not the same; consider 64: 64 >> 5 = 2, 2 & 1 = 0. But 64 > 31.
How about translating the (x >> 5) & 1 != 0 into (x & 0x0020) instead?
compilable testcase: int %test(int* %tmp1) { %tmp = load int* %tmp1 ; <int> [#uses=1] %tmp = cast int %tmp to uint ; <uint> [#uses=1] %tmp2 = shr uint %tmp, ubyte 5 ; <uint> [#uses=1] %tmp2 = cast uint %tmp2 to int ; <int> [#uses=1] %tmp3 = and int %tmp2, 1 ; <int> [#uses=1] %tmp3 = cast int %tmp3 to bool ; <bool> [#uses=1] %tmp34 = cast bool %tmp3 to int ; <int> [#uses=1] ret int %tmp34 }
Fixed. Testcase here: Transforms/InstCombine/2006-09-15-CastToBool.ll Patch here: http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20060911/037892.html BTW, instcombine now reduces the function in the testcase to: int %test(int* %tmp1) { %tmp = load int* %tmp1 ; <int> [#uses=1] %tmp = cast int %tmp to uint ; <uint> [#uses=1] %tmp2 = shr uint %tmp, ubyte 5 ; <uint> [#uses=1] %tmp2 = cast uint %tmp2 to int ; <int> [#uses=1] %tmp34 = and int %tmp2, 1 ; <int> [#uses=1] ret int %tmp34 } The shift is required because the function is required to deliver int 1/0, not a bool. Thanks! -Chris
Fantastic. Thanks Chris!
*** Bug 953 has been marked as a duplicate of this bug. ***