LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 913 - instcombine misoptimizes shr+and to setgt
Summary: instcombine misoptimizes shr+and to setgt
Status: RESOLVED FIXED
Alias: None
Product: libraries
Classification: Unclassified
Component: Scalar Optimizations (show other bugs)
Version: 1.7
Hardware: All All
: P normal
Assignee: Chris Lattner
URL:
Keywords: miscompilation
: 953 (view as bug list)
Depends on:
Blocks:
 
Reported: 2006-09-15 20:00 PDT by Nick Lewycky
Modified: 2018-11-07 00:17 PST (History)
2 users (show)

See Also:
Fixed By Commit(s):


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Nick Lewycky 2006-09-15 20:00:46 PDT
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.
Comment 1 Bill Wendling 2006-09-15 21:45:47 PDT
How about translating the (x >> 5) & 1 != 0 into (x & 0x0020) instead?
Comment 2 Chris Lattner 2006-09-15 22:03:08 PDT
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
}
Comment 3 Chris Lattner 2006-09-15 22:17:13 PDT
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
Comment 4 Nick Lewycky 2006-09-15 22:52:58 PDT
Fantastic. Thanks Chris!
Comment 5 Chris Lattner 2006-10-18 12:40:28 PDT
*** Bug 953 has been marked as a duplicate of this bug. ***