llvm.org GIT mirror llvm / 7312a22
enhance the "change or icmp's into switch" xform to handle one value in an 'or sequence' that it doesn't understand. This allows us to optimize something insane like this: int crud (unsigned char c, unsigned x) { if(((((((((( (int) c <= 32 || (int) c == 46) || (int) c == 44) || (int) c == 58) || (int) c == 59) || (int) c == 60) || (int) c == 62) || (int) c == 34) || (int) c == 92) || (int) c == 39) != 0) foo(); } into: define i32 @crud(i8 zeroext %c, i32 %x) nounwind ssp noredzone { entry: %cmp = icmp ult i8 %c, 33 br i1 %cmp, label %if.then, label %switch.early.test switch.early.test: ; preds = %entry switch i8 %c, label %if.end [ i8 39, label %if.then i8 44, label %if.then i8 58, label %if.then i8 59, label %if.then i8 60, label %if.then i8 62, label %if.then i8 46, label %if.then i8 92, label %if.then i8 34, label %if.then ] by pulling the < comparison out ahead of the newly formed switch. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@121680 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Lattner 8 years ago
2 changed file(s) with 70 addition(s) and 5 deletion(s). Raw diff Collapse all Expand all
300300 Instruction *I = dyn_cast(V);
301301 if (I == 0) return 0;
302302
303 // If this is an icmp against a constant, handle this as one of the cases.
303304 if (ICmpInst *ICI = dyn_cast(I)) {
304305 if (ICI->getPredicate() == (isEQ ? ICmpInst::ICMP_EQ : ICmpInst::ICMP_NE))
305306 if (ConstantInt *C = GetConstantInt(I->getOperand(1), TD)) {
309310 return 0;
310311 }
311312
313 // Otherwise, we can only handle an | or &, depending on isEQ.
312314 if (I->getOpcode() != (isEQ ? Instruction::Or : Instruction::And))
313315 return 0;
314316
317 unsigned NumValsBeforeLHS = Vals.size();
315318 if (Value *LHS = GatherConstantCompares(I->getOperand(0), Vals, Extra, TD,
316319 isEQ)) {
320 unsigned NumVals = Vals.size();
317321 if (Value *RHS = GatherConstantCompares(I->getOperand(1), Vals, Extra, TD,
318322 isEQ)) {
319323 if (LHS == RHS)
320324 return LHS;
321325 }
322 }
326 Vals.resize(NumVals);
327
328 // The RHS of the or/and can't be folded in and we haven't used "Extra" yet,
329 // set it and return success.
330 if (Extra == 0 || Extra == I->getOperand(1)) {
331 Extra = I->getOperand(1);
332 return LHS;
333 }
334
335 Vals.resize(NumValsBeforeLHS);
336 return 0;
337 }
338
339 // If the LHS can't be folded in, but Extra is available and RHS can, try to
340 // use LHS as Extra.
341 if (Extra == 0 || Extra == I->getOperand(0)) {
342 Extra = I->getOperand(0);
343 if (Value *RHS = GatherConstantCompares(I->getOperand(1), Vals, Extra, TD,
344 isEQ))
345 return RHS;
346 Vals.resize(NumValsBeforeLHS);
347 Extra = 0;
348 }
349
323350 return 0;
324351 }
325352
20582085 }
20592086 }
20602087
2061 if (CompVal) {
2088 // We do this transformation if we'll end up creating a switch with at
2089 // least two values if Extra is used.
2090 if (CompVal && (!ExtraCase || Values.size() > 1)) {
20622091 // There might be duplicate constants in the list, which the switch
20632092 // instruction can't handle, remove them now.
20642093 array_pod_sort(Values.begin(), Values.end(), ConstantIntSortPredicate);
20692098 BasicBlock *EdgeBB = BI->getSuccessor(0);
20702099 if (!TrueWhenEqual) std::swap(DefaultBB, EdgeBB);
20712100
2101 // If there are any extra values that couldn't be folded into the switch
2102 // then we evaluate them with an explicit branch first. Split the block
2103 // right before the condbr to handle it.
2104 if (ExtraCase) {
2105 BasicBlock *NewBB = BB->splitBasicBlock(BI, "switch.early.test");
2106 // Remove the uncond branch added to the old block.
2107 TerminatorInst *OldTI = BB->getTerminator();
2108
2109 BranchInst::Create(EdgeBB, NewBB, ExtraCase, OldTI);
2110 OldTI->eraseFromParent();
2111 BB = NewBB;
2112 }
2113
20722114 // Convert pointer to int before we switch.
20732115 if (CompVal->getType()->isPointerTy()) {
20742116 assert(TD && "Cannot switch on pointer without TargetData");
20782120 }
20792121
20802122 // Create the new switch instruction now.
2081 SwitchInst *New = SwitchInst::Create(CompVal, DefaultBB,
2082 Values.size(), BI);
2123 SwitchInst *New =
2124 SwitchInst::Create(CompVal, DefaultBB, Values.size(), BI);
20832125
20842126 // Add all of the 'cases' to the switch instruction.
20852127 for (unsigned i = 0, e = Values.size(); i != e; ++i)
148148 ; CHECK: i32 18, label %UnifiedReturnBlock
149149 ; CHECK: i32 19, label %switch.edge
150150 ; CHECK: ]
151
152151 }
153152
153 define void @test7(i8 zeroext %c, i32 %x) nounwind ssp noredzone {
154 entry:
155 %cmp = icmp ult i32 %x, 32
156 %cmp4 = icmp eq i8 %c, 97
157 %or.cond = or i1 %cmp, %cmp4
158 %cmp9 = icmp eq i8 %c, 99
159 %or.cond11 = or i1 %or.cond, %cmp9
160 br i1 %or.cond11, label %if.then, label %if.end
154161
162 if.then: ; preds = %entry
163 tail call void @foo1() nounwind noredzone
164 ret void
165
166 if.end: ; preds = %entry
167 ret void
168
169 ; CHECK: @test7
170 ; CHECK: %cmp = icmp ult i32 %x, 32
171 ; CHECK: br i1 %cmp, label %if.then, label %switch.early.test
172 ; CHECK: switch.early.test:
173 ; CHECK: switch i8 %c, label %if.end [
174 ; CHECK: i8 99, label %if.then
175 ; CHECK: i8 97, label %if.then
176 ; CHECK: ]
177 }