llvm.org GIT mirror llvm / 2650c76
[InstSimplify] Teach decomposeBitTestICmp to handle non-canonical compares This adds support non-canonical compare predicates. InstSimplify can't rely on canonicalization to have occurred. Differential Revision: https://reviews.llvm.org/D36646 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@310893 91177308-0d34-0410-b5e6-96231b3b80d8 Craig Topper 2 years ago
2 changed file(s) with 36 addition(s) and 20 deletion(s). Raw diff Collapse all Expand all
8080 Mask = APInt::getSignMask(C->getBitWidth());
8181 Pred = ICmpInst::ICMP_NE;
8282 break;
83 case ICmpInst::ICMP_SLE:
84 // X <= -1 is equivalent to (X & SignMask) != 0.
85 if (!C->isAllOnesValue())
86 return false;
87 Mask = APInt::getSignMask(C->getBitWidth());
88 Pred = ICmpInst::ICMP_NE;
89 break;
8390 case ICmpInst::ICMP_SGT:
8491 // X > -1 is equivalent to (X & SignMask) == 0.
8592 if (!C->isAllOnesValue())
93 return false;
94 Mask = APInt::getSignMask(C->getBitWidth());
95 Pred = ICmpInst::ICMP_EQ;
96 break;
97 case ICmpInst::ICMP_SGE:
98 // X >= 0 is equivalent to (X & SignMask) == 0.
99 if (!C->isNullValue())
86100 return false;
87101 Mask = APInt::getSignMask(C->getBitWidth());
88102 Pred = ICmpInst::ICMP_EQ;
94108 Mask = -*C;
95109 Pred = ICmpInst::ICMP_EQ;
96110 break;
111 case ICmpInst::ICMP_ULE:
112 // X <=u 2^n-1 is equivalent to (X & ~(2^n-1)) == 0.
113 if (!(*C + 1).isPowerOf2())
114 return false;
115 Mask = ~*C;
116 Pred = ICmpInst::ICMP_EQ;
117 break;
97118 case ICmpInst::ICMP_UGT:
98119 // X >u 2^n-1 is equivalent to (X & ~(2^n-1)) != 0.
99120 if (!(*C + 1).isPowerOf2())
101122 Mask = ~*C;
102123 Pred = ICmpInst::ICMP_NE;
103124 break;
125 case ICmpInst::ICMP_UGE:
126 // X >=u 2^n is equivalent to (X & ~(2^n-1)) != 0.
127 if (!C->isPowerOf2())
128 return false;
129 Mask = -*C;
130 Pred = ICmpInst::ICMP_NE;
131 break;
104132 }
105133
106134 X = LHS;
4646 }
4747
4848 ; Same as above, but the compare isn't canonical
49 ; TODO: we should be able to simplify this
5049 define i32 @test4noncanon(i32 %X) {
5150 ; CHECK-LABEL: @test4noncanon(
52 ; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[X:%.*]], -1
53 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[X]], -2147483648
54 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[OR]]
55 ; CHECK-NEXT: ret i32 [[COND]]
51 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[X:%.*]], -2147483648
52 ; CHECK-NEXT: ret i32 [[OR]]
5653 ;
5754 %cmp = icmp sle i32 %X, -1
5855 %or = or i32 %X, -2147483648
113110 }
114111
115112 ; Same as above, but the compare isn't canonical
116 ; TODO: we should be able to simplify this
117113 define i32 @test9noncanon(i32 %X) {
118114 ; CHECK-LABEL: @test9noncanon(
119 ; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[X:%.*]], 0
120 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[X]], -2147483648
121 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[OR]], i32 [[X]]
122 ; CHECK-NEXT: ret i32 [[COND]]
115 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[X:%.*]], -2147483648
116 ; CHECK-NEXT: ret i32 [[OR]]
123117 ;
124118 %cmp = icmp sge i32 %X, 0
125119 %or = or i32 %X, -2147483648
171165 }
172166
173167 ; Same as above, but the compare isn't canonical
174 ; TODO: we should be able to simplify this
175168 define i32 @test12noncanon(i32 %X) {
176169 ; CHECK-LABEL: @test12noncanon(
177 ; CHECK-NEXT: [[CMP:%.*]] = icmp ule i32 [[X:%.*]], 3
178 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], 3
179 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[AND]]
180 ; CHECK-NEXT: ret i32 [[COND]]
170 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 3
171 ; CHECK-NEXT: ret i32 [[AND]]
181172 ;
182173 %cmp = icmp ule i32 %X, 3
183174 %and = and i32 %X, 3
197188 }
198189
199190 ; Same as above, but the compare isn't canonical
200 ; TODO: we should be able to simplify this
201191 define i32 @test13noncanon(i32 %X) {
202192 ; CHECK-LABEL: @test13noncanon(
203 ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[X:%.*]], 4
204 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], 3
205 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[AND]], i32 [[X]]
206 ; CHECK-NEXT: ret i32 [[COND]]
193 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 3
194 ; CHECK-NEXT: ret i32 [[AND]]
207195 ;
208196 %cmp = icmp uge i32 %X, 4
209197 %and = and i32 %X, 3