llvm.org GIT mirror llvm / c9f2b5d
[SDAG switch lowering] Fix switch case -> or merging for 0 and INT_MIN The big/small ordering here is based on signed values so SmallValue will be INT_MIN and BigValue 0. This shouldn't be a problem but the code assumed that BigValue always had more bits set than SmallValue. We used to just miss the transformation, but a recent refactoring of mine turned this into an assertion failure. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@239105 91177308-0d34-0410-b5e6-96231b3b80d8 Benjamin Kramer 4 years ago
2 changed file(s) with 25 addition(s) and 10 deletion(s). Raw diff Collapse all Expand all
78067806 const APInt &BigValue = Big.Low->getValue();
78077807
78087808 // Check that there is only one bit different.
7809 if ((BigValue ^ SmallValue).isPowerOf2()) {
7810 // Isolate the common bit.
7811 APInt CommonBit = BigValue & ~SmallValue;
7812 assert((SmallValue | CommonBit) == BigValue &&
7813 CommonBit.countPopulation() == 1 && "Not a common bit?");
7814
7809 APInt CommonBit = BigValue ^ SmallValue;
7810 if (CommonBit.isPowerOf2()) {
78157811 SDValue CondLHS = getValue(Cond);
78167812 EVT VT = CondLHS.getValueType();
78177813 SDLoc DL = getCurSDLoc();
78187814
78197815 SDValue Or = DAG.getNode(ISD::OR, DL, VT, CondLHS,
78207816 DAG.getConstant(CommonBit, DL, VT));
7821 SDValue Cond = DAG.getSetCC(DL, MVT::i1, Or,
7822 DAG.getConstant(BigValue, DL, VT),
7823 ISD::SETEQ);
7817 SDValue Cond = DAG.getSetCC(
7818 DL, MVT::i1, Or, DAG.getConstant(BigValue | SmallValue, DL, VT),
7819 ISD::SETEQ);
78247820
78257821 // Update successor info.
78267822 // Both Small and Big will jump to Small.BB, so we sum up the weights.
0 ; RUN: llc -march=x86 -asm-verbose=false < %s | FileCheck %s
11
22 ; Check that merging switch cases that differ in one bit works.
3 ; CHECK-LABEL: test1
34 ; CHECK: orl $2
45 ; CHECK-NEXT: cmpl $6
56
6 define void @foo(i32 %variable) nounwind {
7 define void @test1(i32 %variable) nounwind {
78 entry:
89 switch i32 %variable, label %if.end [
910 i32 4, label %if.then
1819 ret void
1920 }
2021
22 ; CHECK-LABEL: test2
23 ; CHECK: orl $-2147483648
24 ; CHECK-NEXT: cmpl $-2147483648
25 define void @test2(i32 %variable) nounwind {
26 entry:
27 switch i32 %variable, label %if.end [
28 i32 0, label %if.then
29 i32 -2147483648, label %if.then
30 ]
31
32 if.then:
33 %call = tail call i32 (...) @bar() nounwind
34 ret void
35
36 if.end:
37 ret void
38 }
39
2140 declare i32 @bar(...) nounwind