llvm.org GIT mirror llvm / 4878bbd
[GlobalISel][IRTranslator] Change switch table translation to generate jump tables and range checks. This change makes use of the newly refactored SwitchLoweringUtils code from SelectionDAG to in order to generate jump tables and range checks where appropriate. Much of this code is ported from SDAG with some modifications. We generate G_JUMP_TABLE and G_BRJT instructions when JT opportunities are found. This means that targets which previously relied on the naive one MBB per case stmt translation will now start falling back until they add support for the new opcodes. For range checks, we don't generate any previously unused operations. This just recognizes contiguous ranges of case values and generates a single block per range. Single case value blocks are just a special case of ranges so we get that support almost for free. There are still some optimizations missing that I haven't ported over, and bit-tests are also unimplemented. This patch series is already complex enough. Actual arm64 support for selection of jump tables is coming in a later patch. Differential Revision: https://reviews.llvm.org/D63169 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@364085 91177308-0d34-0410-b5e6-96231b3b80d8 Amara Emerson 11 months ago
6 changed file(s) with 816 addition(s) and 181 deletion(s). Raw diff Collapse all Expand all
2323 #include "llvm/CodeGen/GlobalISel/Types.h"
2424 #include "llvm/CodeGen/SwiftErrorValueTracking.h"
2525 #include "llvm/CodeGen/MachineFunctionPass.h"
26 #include "llvm/CodeGen/SwitchLoweringUtils.h"
2627 #include "llvm/IR/Intrinsics.h"
2728 #include "llvm/Support/Allocator.h"
2829 #include
3637 class CallLowering;
3738 class Constant;
3839 class DataLayout;
40 class FunctionLoweringInfo;
3941 class Instruction;
4042 class MachineBasicBlock;
4143 class MachineFunction;
292294 /// \pre \p U is a branch instruction.
293295 bool translateBr(const User &U, MachineIRBuilder &MIRBuilder);
294296
297 // Begin switch lowering functions.
298 bool emitJumpTableHeader(SwitchCG::JumpTable &JT,
299 SwitchCG::JumpTableHeader &JTH,
300 MachineBasicBlock *SwitchBB,
301 MachineIRBuilder &MIB);
302 void emitJumpTable(SwitchCG::JumpTable &JT, MachineBasicBlock *MBB);
303
304 void emitSwitchCase(SwitchCG::CaseBlock &CB, MachineBasicBlock *SwitchBB,
305 MachineIRBuilder &MIB);
306
307 bool lowerJumpTableWorkItem(SwitchCG::SwitchWorkListItem W,
308 MachineBasicBlock *SwitchMBB,
309 MachineBasicBlock *DefaultMBB,
310 MachineIRBuilder &MIB,
311 MachineFunction::iterator BBI,
312 BranchProbability UnhandledProbs,
313 SwitchCG::CaseClusterIt I,
314 MachineBasicBlock *Fallthrough,
315 bool FallthroughUnreachable);
316
317 bool lowerSwitchRangeWorkItem(SwitchCG::CaseClusterIt I,
318 Value *Cond,
319 MachineBasicBlock *Fallthrough,
320 bool FallthroughUnreachable,
321 BranchProbability UnhandledProbs,
322 MachineBasicBlock *CurMBB,
323 MachineIRBuilder &MIB,
324 MachineBasicBlock *SwitchMBB);
325
326 bool lowerSwitchWorkItem(SwitchCG::SwitchWorkListItem W, Value *Cond,
327 MachineBasicBlock *SwitchMBB,
328 MachineBasicBlock *DefaultMBB,
329 MachineIRBuilder &MIB);
330
295331 bool translateSwitch(const User &U, MachineIRBuilder &MIRBuilder);
332 // End switch lowering section.
296333
297334 bool translateIndirectBr(const User &U, MachineIRBuilder &MIRBuilder);
298335
480517 /// Current optimization remark emitter. Used to report failures.
481518 std::unique_ptr ORE;
482519
520 FunctionLoweringInfo FuncInfo;
521
522 // True when either the Target Machine specifies no optimizations or the
523 // function has the optnone attribute.
524 bool EnableOpts = false;
525
526 /// Switch analysis and optimization.
527 class GISelSwitchLowering : public SwitchCG::SwitchLowering {
528 public:
529 GISelSwitchLowering(IRTranslator *irt, FunctionLoweringInfo &funcinfo)
530 : SwitchLowering(funcinfo), IRT(irt) {
531 assert(irt && "irt is null!");
532 }
533
534 virtual void addSuccessorWithProb(
535 MachineBasicBlock *Src, MachineBasicBlock *Dst,
536 BranchProbability Prob = BranchProbability::getUnknown()) override {
537 IRT->addSuccessorWithProb(Src, Dst, Prob);
538 }
539
540 virtual ~GISelSwitchLowering() = default;
541
542 private:
543 IRTranslator *IRT;
544 };
545
546 std::unique_ptr SL;
547
483548 // * Insert all the code needed to materialize the constants
484549 // at the proper place. E.g., Entry block or dominator block
485550 // of each constant depending on how fancy we want to be.
486551 // * Clear the different maps.
487552 void finalizeFunction();
553
554 // Handle emitting jump tables for each basic block.
555 void finalizeBasicBlock();
488556
489557 /// Get the VRegs that represent \p Val.
490558 /// Non-aggregate types have just one corresponding VReg and the list can be
535603 return RemappedEdge->second;
536604 return SmallVector(1, &getMBB(*Edge.first));
537605 }
606
607 /// Return branch probability calculated by BranchProbabilityInfo for IR
608 /// blocks.
609 BranchProbability getEdgeProbability(const MachineBasicBlock *Src,
610 const MachineBasicBlock *Dst) const;
611
612 void addSuccessorWithProb(MachineBasicBlock *Src, MachineBasicBlock *Dst,
613 BranchProbability Prob);
538614
539615 public:
540616 // Ctor, nothing fancy.
100100 /// SDISel for the code generation of additional basic blocks needed by
101101 /// multi-case switch statements.
102102 struct CaseBlock {
103 // The condition code to use for the case block's setcc node.
104 // Besides the integer condition codes, this can also be SETTRUE, in which
105 // case no comparison gets emitted.
106 ISD::CondCode CC;
103 // For the GISel interface.
104 struct PredInfoPair {
105 CmpInst::Predicate Pred;
106 // Set when no comparison should be emitted.
107 bool NoCmp;
108 };
109 union {
110 // The condition code to use for the case block's setcc node.
111 // Besides the integer condition codes, this can also be SETTRUE, in which
112 // case no comparison gets emitted.
113 ISD::CondCode CC;
114 struct PredInfoPair PredInfo;
115 };
107116
108117 // The LHS/MHS/RHS of the comparison to emit.
109118 // Emit by default LHS op RHS. MHS is used for range comparisons:
119128 /// The debug location of the instruction this CaseBlock was
120129 /// produced from.
121130 SDLoc DL;
131 DebugLoc DbgLoc;
122132
123133 // Branch weights.
124134 BranchProbability TrueProb, FalseProb;
125135
136 // Constructor for SelectionDAG.
126137 CaseBlock(ISD::CondCode cc, const Value *cmplhs, const Value *cmprhs,
127138 const Value *cmpmiddle, MachineBasicBlock *truebb,
128139 MachineBasicBlock *falsebb, MachineBasicBlock *me, SDLoc dl,
131142 : CC(cc), CmpLHS(cmplhs), CmpMHS(cmpmiddle), CmpRHS(cmprhs),
132143 TrueBB(truebb), FalseBB(falsebb), ThisBB(me), DL(dl),
133144 TrueProb(trueprob), FalseProb(falseprob) {}
145
146 // Constructor for GISel.
147 CaseBlock(CmpInst::Predicate pred, bool nocmp, const Value *cmplhs,
148 const Value *cmprhs, const Value *cmpmiddle,
149 MachineBasicBlock *truebb, MachineBasicBlock *falsebb,
150 MachineBasicBlock *me, DebugLoc dl,
151 BranchProbability trueprob = BranchProbability::getUnknown(),
152 BranchProbability falseprob = BranchProbability::getUnknown())
153 : PredInfo({pred, nocmp}), CmpLHS(cmplhs), CmpMHS(cmpmiddle),
154 CmpRHS(cmprhs), TrueBB(truebb), FalseBB(falsebb), ThisBB(me),
155 DbgLoc(dl), TrueProb(trueprob), FalseProb(falseprob) {}
134156 };
135157
136158 struct JumpTable {
1414 #include "llvm/ADT/ScopeExit.h"
1515 #include "llvm/ADT/SmallSet.h"
1616 #include "llvm/ADT/SmallVector.h"
17 #include "llvm/Analysis/BranchProbabilityInfo.h"
1718 #include "llvm/Analysis/OptimizationRemarkEmitter.h"
1819 #include "llvm/Analysis/ValueTracking.h"
1920 #include "llvm/CodeGen/Analysis.h"
21 #include "llvm/CodeGen/FunctionLoweringInfo.h"
2022 #include "llvm/CodeGen/GlobalISel/CallLowering.h"
2123 #include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
2224 #include "llvm/CodeGen/LowLevelType.h"
401403 return true;
402404 }
403405
404 bool IRTranslator::translateSwitch(const User &U,
405 MachineIRBuilder &MIRBuilder) {
406 // For now, just translate as a chain of conditional branches.
407 // FIXME: could we share most of the logic/code in
408 // SelectionDAGBuilder::visitSwitch between SelectionDAG and GlobalISel?
409 // At first sight, it seems most of the logic in there is independent of
410 // SelectionDAG-specifics and a lot of work went in to optimize switch
411 // lowering in there.
412
413 const SwitchInst &SwInst = cast(U);
414 const unsigned SwCondValue = getOrCreateVReg(*SwInst.getCondition());
415 const BasicBlock *OrigBB = SwInst.getParent();
416
417 LLT LLTi1 = getLLTForType(*Type::getInt1Ty(U.getContext()), *DL);
418 for (auto &CaseIt : SwInst.cases()) {
419 const unsigned CaseValueReg = getOrCreateVReg(*CaseIt.getCaseValue());
420 const unsigned Tst = MRI->createGenericVirtualRegister(LLTi1);
421 MIRBuilder.buildICmp(CmpInst::ICMP_EQ, Tst, CaseValueReg, SwCondValue);
422 MachineBasicBlock &CurMBB = MIRBuilder.getMBB();
423 const BasicBlock *TrueBB = CaseIt.getCaseSuccessor();
424 MachineBasicBlock &TrueMBB = getMBB(*TrueBB);
425
426 MIRBuilder.buildBrCond(Tst, TrueMBB);
427 CurMBB.addSuccessor(&TrueMBB);
428 addMachineCFGPred({OrigBB, TrueBB}, &CurMBB);
429
430 MachineBasicBlock *FalseMBB =
431 MF->CreateMachineBasicBlock(SwInst.getParent());
432 // Insert the comparison blocks one after the other.
433 MF->insert(std::next(CurMBB.getIterator()), FalseMBB);
434 MIRBuilder.buildBr(*FalseMBB);
435 CurMBB.addSuccessor(FalseMBB);
436
437 MIRBuilder.setMBB(*FalseMBB);
438 }
439 // handle default case
440 const BasicBlock *DefaultBB = SwInst.getDefaultDest();
441 MachineBasicBlock &DefaultMBB = getMBB(*DefaultBB);
442 MIRBuilder.buildBr(DefaultMBB);
443 MachineBasicBlock &CurMBB = MIRBuilder.getMBB();
444 CurMBB.addSuccessor(&DefaultMBB);
445 addMachineCFGPred({OrigBB, DefaultBB}, &CurMBB);
406 void IRTranslator::addSuccessorWithProb(MachineBasicBlock *Src,
407 MachineBasicBlock *Dst,
408 BranchProbability Prob) {
409 if (!FuncInfo.BPI) {
410 Src->addSuccessorWithoutProb(Dst);
411 return;
412 }
413 if (Prob.isUnknown())
414 Prob = getEdgeProbability(Src, Dst);
415 Src->addSuccessor(Dst, Prob);
416 }
417
418 BranchProbability
419 IRTranslator::getEdgeProbability(const MachineBasicBlock *Src,
420 const MachineBasicBlock *Dst) const {
421 const BasicBlock *SrcBB = Src->getBasicBlock();
422 const BasicBlock *DstBB = Dst->getBasicBlock();
423 if (!FuncInfo.BPI) {
424 // If BPI is not available, set the default probability as 1 / N, where N is
425 // the number of successors.
426 auto SuccSize = std::max(succ_size(SrcBB), 1);
427 return BranchProbability(1, SuccSize);
428 }
429 return FuncInfo.BPI->getEdgeProbability(SrcBB, DstBB);
430 }
431
432 bool IRTranslator::translateSwitch(const User &U, MachineIRBuilder &MIB) {
433 using namespace SwitchCG;
434 // Extract cases from the switch.
435 const SwitchInst &SI = cast(U);
436 BranchProbabilityInfo *BPI = FuncInfo.BPI;
437 CaseClusterVector Clusters;
438 Clusters.reserve(SI.getNumCases());
439 for (auto &I : SI.cases()) {
440 MachineBasicBlock *Succ = &getMBB(*I.getCaseSuccessor());
441 assert(Succ && "Could not find successor mbb in mapping");
442 const ConstantInt *CaseVal = I.getCaseValue();
443 BranchProbability Prob =
444 BPI ? BPI->getEdgeProbability(SI.getParent(), I.getSuccessorIndex())
445 : BranchProbability(1, SI.getNumCases() + 1);
446 Clusters.push_back(CaseCluster::range(CaseVal, CaseVal, Succ, Prob));
447 }
448
449 MachineBasicBlock *DefaultMBB = &getMBB(*SI.getDefaultDest());
450
451 // Cluster adjacent cases with the same destination. We do this at all
452 // optimization levels because it's cheap to do and will make codegen faster
453 // if there are many clusters.
454 sortAndRangeify(Clusters);
455
456 MachineBasicBlock *SwitchMBB = &getMBB(*SI.getParent());
457
458 // If there is only the default destination, jump there directly.
459 if (Clusters.empty()) {
460 SwitchMBB->addSuccessor(DefaultMBB);
461 if (DefaultMBB != SwitchMBB->getNextNode())
462 MIB.buildBr(*DefaultMBB);
463 return true;
464 }
465
466 SL->findJumpTables(Clusters, &SI, DefaultMBB);
467
468 LLVM_DEBUG({
469 dbgs() << "Case clusters: ";
470 for (const CaseCluster &C : Clusters) {
471 if (C.Kind == CC_JumpTable)
472 dbgs() << "JT:";
473 if (C.Kind == CC_BitTests)
474 dbgs() << "BT:";
475
476 C.Low->getValue().print(dbgs(), true);
477 if (C.Low != C.High) {
478 dbgs() << '-';
479 C.High->getValue().print(dbgs(), true);
480 }
481 dbgs() << ' ';
482 }
483 dbgs() << '\n';
484 });
485
486 assert(!Clusters.empty());
487 SwitchWorkList WorkList;
488 CaseClusterIt First = Clusters.begin();
489 CaseClusterIt Last = Clusters.end() - 1;
490 auto DefaultProb = getEdgeProbability(SwitchMBB, DefaultMBB);
491 WorkList.push_back({SwitchMBB, First, Last, nullptr, nullptr, DefaultProb});
492
493 // FIXME: At the moment we don't do any splitting optimizations here like
494 // SelectionDAG does, so this worklist only has one entry.
495 while (!WorkList.empty()) {
496 SwitchWorkListItem W = WorkList.back();
497 WorkList.pop_back();
498 if (!lowerSwitchWorkItem(W, SI.getCondition(), SwitchMBB, DefaultMBB, MIB))
499 return false;
500 }
501 return true;
502 }
503
504 void IRTranslator::emitJumpTable(SwitchCG::JumpTable &JT,
505 MachineBasicBlock *MBB) {
506 // Emit the code for the jump table
507 assert(JT.Reg != -1U && "Should lower JT Header first!");
508 MachineIRBuilder MIB(*MBB->getParent());
509 MIB.setMBB(*MBB);
510 MIB.setDebugLoc(CurBuilder->getDebugLoc());
511
512 Type *PtrIRTy = Type::getInt8PtrTy(MF->getFunction().getContext());
513 const LLT PtrTy = getLLTForType(*PtrIRTy, *DL);
514
515 auto Table = MIB.buildJumpTable(PtrTy, JT.JTI);
516 MIB.buildBrJT(Table.getReg(0), JT.JTI, JT.Reg);
517 }
518
519 bool IRTranslator::emitJumpTableHeader(SwitchCG::JumpTable &JT,
520 SwitchCG::JumpTableHeader &JTH,
521 MachineBasicBlock *SwitchBB,
522 MachineIRBuilder &MIB) {
523 DebugLoc dl = MIB.getDebugLoc();
524
525 const Value &SValue = *JTH.SValue;
526 // Subtract the lowest switch case value from the value being switched on.
527 const LLT SwitchTy = getLLTForType(*SValue.getType(), *DL);
528 unsigned SwitchOpReg = getOrCreateVReg(SValue);
529 auto FirstCst = MIB.buildConstant(SwitchTy, JTH.First);
530 auto Sub = MIB.buildSub({SwitchTy}, SwitchOpReg, FirstCst);
531
532 // This value may be smaller or larger than the target's pointer type, and
533 // therefore require extension or truncating.
534 Type *PtrIRTy = SValue.getType()->getPointerTo();
535 const LLT PtrScalarTy = LLT::scalar(DL->getTypeSizeInBits(PtrIRTy));
536 Sub = MIB.buildZExtOrTrunc(PtrScalarTy, Sub);
537
538 JT.Reg = Sub.getReg(0);
539
540 if (JTH.OmitRangeCheck) {
541 if (JT.MBB != SwitchBB->getNextNode())
542 MIB.buildBr(*JT.MBB);
543 return true;
544 }
545
546 // Emit the range check for the jump table, and branch to the default block
547 // for the switch statement if the value being switched on exceeds the
548 // largest case in the switch.
549 auto Cst = getOrCreateVReg(
550 *ConstantInt::get(SValue.getType(), JTH.Last - JTH.First));
551 Cst = MIB.buildZExtOrTrunc(PtrScalarTy, Cst).getReg(0);
552 auto Cmp = MIB.buildICmp(CmpInst::ICMP_UGT, LLT::scalar(1), Sub, Cst);
553
554 auto BrCond = MIB.buildBrCond(Cmp.getReg(0), *JT.Default);
555
556 // Avoid emitting unnecessary branches to the next block.
557 if (JT.MBB != SwitchBB->getNextNode())
558 BrCond = MIB.buildBr(*JT.MBB);
559 return true;
560 }
561
562 void IRTranslator::emitSwitchCase(SwitchCG::CaseBlock &CB,
563 MachineBasicBlock *SwitchBB,
564 MachineIRBuilder &MIB) {
565 unsigned CondLHS = getOrCreateVReg(*CB.CmpLHS);
566 unsigned Cond = 0;
567 DebugLoc OldDbgLoc = MIB.getDebugLoc();
568 MIB.setDebugLoc(CB.DbgLoc);
569 MIB.setMBB(*CB.ThisBB);
570
571 if (CB.PredInfo.NoCmp) {
572 // Branch or fall through to TrueBB.
573 addSuccessorWithProb(CB.ThisBB, CB.TrueBB, CB.TrueProb);
574 addMachineCFGPred({SwitchBB->getBasicBlock(), CB.TrueBB->getBasicBlock()},
575 CB.ThisBB);
576 CB.ThisBB->normalizeSuccProbs();
577 if (CB.TrueBB != CB.ThisBB->getNextNode())
578 MIB.buildBr(*CB.TrueBB);
579 MIB.setDebugLoc(OldDbgLoc);
580 return;
581 }
582
583 const LLT i1Ty = LLT::scalar(1);
584 // Build the compare.
585 if (!CB.CmpMHS) {
586 unsigned CondRHS = getOrCreateVReg(*CB.CmpRHS);
587 Cond = MIB.buildICmp(CB.PredInfo.Pred, i1Ty, CondLHS, CondRHS).getReg(0);
588 } else {
589 assert(CB.PredInfo.Pred == CmpInst::ICMP_ULE &&
590 "Can only handle ULE ranges");
591
592 const APInt& Low = cast(CB.CmpLHS)->getValue();
593 const APInt& High = cast(CB.CmpRHS)->getValue();
594
595 unsigned CmpOpReg = getOrCreateVReg(*CB.CmpMHS);
596 if (cast(CB.CmpLHS)->isMinValue(true)) {
597 unsigned CondRHS = getOrCreateVReg(*CB.CmpRHS);
598 Cond =
599 MIB.buildICmp(CmpInst::ICMP_ULE, i1Ty, CmpOpReg, CondRHS).getReg(0);
600 } else {
601 const LLT &CmpTy = MRI->getType(CmpOpReg);
602 auto Sub = MIB.buildSub({CmpTy}, CmpOpReg, CondLHS);
603 auto Diff = MIB.buildConstant(CmpTy, High - Low);
604 Cond = MIB.buildICmp(CmpInst::ICMP_ULE, i1Ty, Sub, Diff).getReg(0);
605 }
606 }
607
608 // Update successor info
609 addSuccessorWithProb(CB.ThisBB, CB.TrueBB, CB.TrueProb);
610
611 addMachineCFGPred({SwitchBB->getBasicBlock(), CB.TrueBB->getBasicBlock()},
612 CB.ThisBB);
613
614 // TrueBB and FalseBB are always different unless the incoming IR is
615 // degenerate. This only happens when running llc on weird IR.
616 if (CB.TrueBB != CB.FalseBB)
617 addSuccessorWithProb(CB.ThisBB, CB.FalseBB, CB.FalseProb);
618 CB.ThisBB->normalizeSuccProbs();
619
620 addMachineCFGPred({SwitchBB->getBasicBlock(), CB.FalseBB->getBasicBlock()},
621 CB.ThisBB);
622 // If the lhs block is the next block, invert the condition so that we can
623 // fall through to the lhs instead of the rhs block.
624 if (CB.TrueBB == CB.ThisBB->getNextNode()) {
625 std::swap(CB.TrueBB, CB.FalseBB);
626 auto True = MIB.buildConstant(i1Ty, 1);
627 Cond = MIB.buildInstr(TargetOpcode::G_XOR, {i1Ty}, {Cond, True}, None)
628 .getReg(0);
629 }
630
631 MIB.buildBrCond(Cond, *CB.TrueBB);
632 MIB.buildBr(*CB.FalseBB);
633 MIB.setDebugLoc(OldDbgLoc);
634 }
635
636 bool IRTranslator::lowerJumpTableWorkItem(SwitchCG::SwitchWorkListItem W,
637 MachineBasicBlock *SwitchMBB,
638 MachineBasicBlock *DefaultMBB,
639 MachineIRBuilder &MIB,
640 MachineFunction::iterator BBI,
641 BranchProbability UnhandledProbs,
642 SwitchCG::CaseClusterIt I,
643 MachineBasicBlock *Fallthrough,
644 bool FallthroughUnreachable) {
645 using namespace SwitchCG;
646 MachineFunction *CurMF = SwitchMBB->getParent();
647 // FIXME: Optimize away range check based on pivot comparisons.
648 JumpTableHeader *JTH = &SL->JTCases[I->JTCasesIndex].first;
649 SwitchCG::JumpTable *JT = &SL->JTCases[I->JTCasesIndex].second;
650 BranchProbability DefaultProb = W.DefaultProb;
651 MachineBasicBlock *CurMBB = W.MBB;
652
653 // The jump block hasn't been inserted yet; insert it here.
654 MachineBasicBlock *JumpMBB = JT->MBB;
655 CurMF->insert(BBI, JumpMBB);
656
657 // Since the jump table block is separate from the switch block, we need
658 // to keep track of it as a machine predecessor to the default block,
659 // otherwise we lose the phi edges.
660 addMachineCFGPred({SwitchMBB->getBasicBlock(), DefaultMBB->getBasicBlock()},
661 SwitchMBB);
662 addMachineCFGPred({SwitchMBB->getBasicBlock(), DefaultMBB->getBasicBlock()},
663 JumpMBB);
664
665 auto JumpProb = I->Prob;
666 auto FallthroughProb = UnhandledProbs;
667
668 // If the default statement is a target of the jump table, we evenly
669 // distribute the default probability to successors of CurMBB. Also
670 // update the probability on the edge from JumpMBB to Fallthrough.
671 for (MachineBasicBlock::succ_iterator SI = JumpMBB->succ_begin(),
672 SE = JumpMBB->succ_end();
673 SI != SE; ++SI) {
674 if (*SI == DefaultMBB) {
675 JumpProb += DefaultProb / 2;
676 FallthroughProb -= DefaultProb / 2;
677 JumpMBB->setSuccProbability(SI, DefaultProb / 2);
678 JumpMBB->normalizeSuccProbs();
679 break;
680 }
681 }
682
683 // Skip the range check if the fallthrough block is unreachable.
684 if (FallthroughUnreachable)
685 JTH->OmitRangeCheck = true;
686
687 if (!JTH->OmitRangeCheck)
688 addSuccessorWithProb(CurMBB, Fallthrough, FallthroughProb);
689 addSuccessorWithProb(CurMBB, JumpMBB, JumpProb);
690 CurMBB->normalizeSuccProbs();
691
692 // The jump table header will be inserted in our current block, do the
693 // range check, and fall through to our fallthrough block.
694 JTH->HeaderBB = CurMBB;
695 JT->Default = Fallthrough; // FIXME: Move Default to JumpTableHeader.
696
697 // If we're in the right place, emit the jump table header right now.
698 if (CurMBB == SwitchMBB) {
699 if (!emitJumpTableHeader(*JT, *JTH, SwitchMBB, MIB))
700 return false;
701 JTH->Emitted = true;
702 }
703 return true;
704 }
705 bool IRTranslator::lowerSwitchRangeWorkItem(SwitchCG::CaseClusterIt I,
706 Value *Cond,
707 MachineBasicBlock *Fallthrough,
708 bool FallthroughUnreachable,
709 BranchProbability UnhandledProbs,
710 MachineBasicBlock *CurMBB,
711 MachineIRBuilder &MIB,
712 MachineBasicBlock *SwitchMBB) {
713 using namespace SwitchCG;
714 const Value *RHS, *LHS, *MHS;
715 CmpInst::Predicate Pred;
716 if (I->Low == I->High) {
717 // Check Cond == I->Low.
718 Pred = CmpInst::ICMP_EQ;
719 LHS = Cond;
720 RHS = I->Low;
721 MHS = nullptr;
722 } else {
723 // Check I->Low <= Cond <= I->High.
724 Pred = CmpInst::ICMP_ULE;
725 LHS = I->Low;
726 MHS = Cond;
727 RHS = I->High;
728 }
729
730 // If Fallthrough is unreachable, fold away the comparison.
731 // The false probability is the sum of all unhandled cases.
732 CaseBlock CB(Pred, FallthroughUnreachable, LHS, RHS, MHS, I->MBB, Fallthrough,
733 CurMBB, MIB.getDebugLoc(), I->Prob, UnhandledProbs);
734
735 emitSwitchCase(CB, SwitchMBB, MIB);
736 return true;
737 }
738
739 bool IRTranslator::lowerSwitchWorkItem(SwitchCG::SwitchWorkListItem W,
740 Value *Cond,
741 MachineBasicBlock *SwitchMBB,
742 MachineBasicBlock *DefaultMBB,
743 MachineIRBuilder &MIB) {
744 using namespace SwitchCG;
745 MachineFunction *CurMF = FuncInfo.MF;
746 MachineBasicBlock *NextMBB = nullptr;
747 MachineFunction::iterator BBI(W.MBB);
748 if (++BBI != FuncInfo.MF->end())
749 NextMBB = &*BBI;
750
751 if (EnableOpts) {
752 // Here, we order cases by probability so the most likely case will be
753 // checked first. However, two clusters can have the same probability in
754 // which case their relative ordering is non-deterministic. So we use Low
755 // as a tie-breaker as clusters are guaranteed to never overlap.
756 llvm::sort(W.FirstCluster, W.LastCluster + 1,
757 [](const CaseCluster &a, const CaseCluster &b) {
758 return a.Prob != b.Prob
759 ? a.Prob > b.Prob
760 : a.Low->getValue().slt(b.Low->getValue());
761 });
762
763 // Rearrange the case blocks so that the last one falls through if possible
764 // without changing the order of probabilities.
765 for (CaseClusterIt I = W.LastCluster; I > W.FirstCluster;) {
766 --I;
767 if (I->Prob > W.LastCluster->Prob)
768 break;
769 if (I->Kind == CC_Range && I->MBB == NextMBB) {
770 std::swap(*I, *W.LastCluster);
771 break;
772 }
773 }
774 }
775
776 // Compute total probability.
777 BranchProbability DefaultProb = W.DefaultProb;
778 BranchProbability UnhandledProbs = DefaultProb;
779 for (CaseClusterIt I = W.FirstCluster; I <= W.LastCluster; ++I)
780 UnhandledProbs += I->Prob;
781
782 MachineBasicBlock *CurMBB = W.MBB;
783 for (CaseClusterIt I = W.FirstCluster, E = W.LastCluster; I <= E; ++I) {
784 bool FallthroughUnreachable = false;
785 MachineBasicBlock *Fallthrough;
786 if (I == W.LastCluster) {
787 // For the last cluster, fall through to the default destination.
788 Fallthrough = DefaultMBB;
789 FallthroughUnreachable = isa(
790 DefaultMBB->getBasicBlock()->getFirstNonPHIOrDbg());
791 } else {
792 Fallthrough = CurMF->CreateMachineBasicBlock(CurMBB->getBasicBlock());
793 CurMF->insert(BBI, Fallthrough);
794 }
795 UnhandledProbs -= I->Prob;
796
797 switch (I->Kind) {
798 case CC_BitTests: {
799 LLVM_DEBUG(dbgs() << "Switch to bit test optimization unimplemented");
800 return false; // Bit tests currently unimplemented.
801 }
802 case CC_JumpTable: {
803 if (!lowerJumpTableWorkItem(W, SwitchMBB, DefaultMBB, MIB, BBI,
804 UnhandledProbs, I, Fallthrough,
805 FallthroughUnreachable)) {
806 LLVM_DEBUG(dbgs() << "Failed to lower jump table");
807 return false;
808 }
809 break;
810 }
811 case CC_Range: {
812 if (!lowerSwitchRangeWorkItem(I, Cond, Fallthrough,
813 FallthroughUnreachable, UnhandledProbs,
814 CurMBB, MIB, SwitchMBB)) {
815 LLVM_DEBUG(dbgs() << "Failed to lower switch range");
816 return false;
817 }
818 break;
819 }
820 }
821 CurMBB = Fallthrough;
822 }
446823
447824 return true;
448825 }
16882065 Verifier.setCurrentInst(PI);
16892066 #endif // ifndef NDEBUG
16902067
1691 // All MachineBasicBlocks exist, add them to the PHI. We assume IRTranslator
1692 // won't create extra control flow here, otherwise we need to find the
1693 // dominating predecessor here (or perhaps force the weirder IRTranslators
1694 // to provide a simple boundary).
1695 SmallSet HandledPreds;
1696
2068 SmallSet SeenPreds;
16972069 for (unsigned i = 0; i < PI->getNumIncomingValues(); ++i) {
16982070 auto IRPred = PI->getIncomingBlock(i);
1699 if (HandledPreds.count(IRPred))
1700 continue;
1701
1702 HandledPreds.insert(IRPred);
17032071 ArrayRef ValRegs = getOrCreateVRegs(*PI->getIncomingValue(i));
17042072 for (auto Pred : getMachinePredBBs({IRPred, PI->getParent()})) {
1705 assert(Pred->isSuccessor(ComponentPHIs[0]->getParent()) &&
1706 "incorrect CFG at MachineBasicBlock level");
2073 if (SeenPreds.count(Pred))
2074 continue;
2075 SeenPreds.insert(Pred);
17072076 for (unsigned j = 0; j < ValRegs.size(); ++j) {
17082077 MachineInstrBuilder MIB(*MF, ComponentPHIs[j]);
17092078 MIB.addUse(ValRegs[j]);
18072176 return true;
18082177 }
18092178
2179 void IRTranslator::finalizeBasicBlock() {
2180 for (auto &JTCase : SL->JTCases)
2181 emitJumpTable(JTCase.second, JTCase.second.MBB);
2182 SL->JTCases.clear();
2183 }
2184
18102185 void IRTranslator::finalizeFunction() {
18112186 // Release the memory used by the different maps we
18122187 // needed during the translation.
18192194 // destroying it twice (in ~IRTranslator() and ~LLVMContext())
18202195 EntryBuilder.reset();
18212196 CurBuilder.reset();
2197 FuncInfo.clear();
18222198 }
18232199
18242200 bool IRTranslator::runOnMachineFunction(MachineFunction &CurMF) {
18512227 MRI = &MF->getRegInfo();
18522228 DL = &F.getParent()->getDataLayout();
18532229 ORE = llvm::make_unique(&F);
2230 FuncInfo.MF = MF;
2231 FuncInfo.BPI = nullptr;
2232 const auto &TLI = *MF->getSubtarget().getTargetLowering();
2233 const TargetMachine &TM = MF->getTarget();
2234 SL = make_unique(this, FuncInfo);
2235 SL->init(TLI, TM, *DL);
2236
2237 EnableOpts = TM.getOptLevel() != CodeGenOpt::None && !skipFunction(F);
18542238
18552239 assert(PendingPHIs.empty() && "stale PHIs");
18562240
19742358 reportTranslationError(*MF, *TPC, *ORE, R);
19752359 return false;
19762360 }
2361
2362 finalizeBasicBlock();
19772363 }
19782364 #ifndef NDEBUG
19792365 WrapperObserver.removeObserver(&Verifier);
5151 assert(Clusters[i - 1].High->getValue().slt(Clusters[i].Low->getValue()));
5252 #endif
5353
54 assert(TLI && "TLI not set!");
5455 if (!TLI->areJTsAllowed(SI->getParent()->getParent()))
5556 return;
5657
0 ; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
1 ; RUN: llc -mtriple aarch64 -O0 -aarch64-enable-atomic-cfg-tidy=0 -stop-after=irtranslator -global-isel -verify-machineinstrs %s -o - 2>&1 | FileCheck %s
2
3 define i32 @switch(i32 %argc) {
4 ; CHECK-LABEL: name: switch
5 ; CHECK: bb.1.entry:
6 ; CHECK: successors: %bb.3(0x40000000), %bb.6(0x40000000)
7 ; CHECK: liveins: $w0
8 ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
9 ; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 100
10 ; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 200
11 ; CHECK: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
12 ; CHECK: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
13 ; CHECK: [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
14 ; CHECK: [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[C]]
15 ; CHECK: G_BRCOND [[ICMP]](s1), %bb.3
16 ; CHECK: G_BR %bb.6
17 ; CHECK: bb.6.entry:
18 ; CHECK: successors: %bb.4(0x40000000), %bb.2(0x40000000)
19 ; CHECK: [[ICMP1:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[C1]]
20 ; CHECK: G_BRCOND [[ICMP1]](s1), %bb.4
21 ; CHECK: G_BR %bb.2
22 ; CHECK: bb.2.default:
23 ; CHECK: successors: %bb.5(0x80000000)
24 ; CHECK: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[COPY]], [[C4]]
25 ; CHECK: G_BR %bb.5
26 ; CHECK: bb.3.case100:
27 ; CHECK: successors: %bb.5(0x80000000)
28 ; CHECK: [[ADD1:%[0-9]+]]:_(s32) = G_ADD [[COPY]], [[C3]]
29 ; CHECK: G_BR %bb.5
30 ; CHECK: bb.4.case200:
31 ; CHECK: successors: %bb.5(0x80000000)
32 ; CHECK: [[ADD2:%[0-9]+]]:_(s32) = G_ADD [[COPY]], [[C2]]
33 ; CHECK: bb.5.return:
34 ; CHECK: [[PHI:%[0-9]+]]:_(s32) = G_PHI [[ADD]](s32), %bb.2, [[ADD1]](s32), %bb.3, [[ADD2]](s32), %bb.4
35 ; CHECK: $w0 = COPY [[PHI]](s32)
36 ; CHECK: RET_ReallyLR implicit $w0
37 entry:
38 switch i32 %argc, label %default [
39 i32 100, label %case100
40 i32 200, label %case200
41 ]
42
43 default:
44 %tmp0 = add i32 %argc, 0
45 br label %return
46
47 case100:
48 %tmp1 = add i32 %argc, 1
49 br label %return
50
51 case200:
52 %tmp2 = add i32 %argc, 2
53 br label %return
54
55 return:
56 %res = phi i32 [ %tmp0, %default ], [ %tmp1, %case100 ], [ %tmp2, %case200 ]
57 ret i32 %res
58 }
59
60 define i32 @test_cfg_remap(i32 %in) {
61 ; CHECK-LABEL: name: test_cfg_remap
62 ; CHECK: bb.1.entry:
63 ; CHECK: successors: %bb.2(0x40000000), %bb.5(0x40000000)
64 ; CHECK: liveins: $w0
65 ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
66 ; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
67 ; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 57
68 ; CHECK: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
69 ; CHECK: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 42
70 ; CHECK: [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[C]]
71 ; CHECK: G_BRCOND [[ICMP]](s1), %bb.2
72 ; CHECK: G_BR %bb.5
73 ; CHECK: bb.5.entry:
74 ; CHECK: successors: %bb.3(0x40000000), %bb.4(0x40000000)
75 ; CHECK: [[ICMP1:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[C1]]
76 ; CHECK: G_BRCOND [[ICMP1]](s1), %bb.3
77 ; CHECK: G_BR %bb.4
78 ; CHECK: bb.2.next:
79 ; CHECK: successors: %bb.4(0x80000000)
80 ; CHECK: G_BR %bb.4
81 ; CHECK: bb.3.other:
82 ; CHECK: $w0 = COPY [[DEF]](s32)
83 ; CHECK: RET_ReallyLR implicit $w0
84 ; CHECK: bb.4.phi.block:
85 ; CHECK: [[PHI:%[0-9]+]]:_(s32) = G_PHI [[C]](s32), %bb.5, [[C2]](s32), %bb.2
86 ; CHECK: $w0 = COPY [[PHI]](s32)
87 ; CHECK: RET_ReallyLR implicit $w0
88 entry:
89 switch i32 %in, label %phi.block [i32 1, label %next
90 i32 57, label %other]
91
92 next:
93 br label %phi.block
94
95 other:
96 ret i32 undef
97
98 phi.block:
99 %res = phi i32 [1, %entry], [42, %next]
100 ret i32 %res
101 }
102
103 define i32 @test_cfg_remap_multiple_preds(i32 %in) {
104 ; CHECK-LABEL: name: test_cfg_remap_multiple_preds
105 ; CHECK: bb.1.entry:
106 ; CHECK: successors: %bb.3(0x40000000), %bb.6(0x40000000)
107 ; CHECK: liveins: $w0
108 ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
109 ; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
110 ; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 57
111 ; CHECK: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 128
112 ; CHECK: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
113 ; CHECK: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 12
114 ; CHECK: [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 42
115 ; CHECK: [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[C]]
116 ; CHECK: G_BRCOND [[ICMP]](s1), %bb.3
117 ; CHECK: G_BR %bb.6
118 ; CHECK: bb.6.entry:
119 ; CHECK: successors: %bb.4(0x40000000), %bb.7(0x40000000)
120 ; CHECK: [[ICMP1:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[C1]]
121 ; CHECK: G_BRCOND [[ICMP1]](s1), %bb.4
122 ; CHECK: G_BR %bb.7
123 ; CHECK: bb.7.entry:
124 ; CHECK: successors: %bb.5(0x40000000), %bb.8(0x40000000)
125 ; CHECK: [[ICMP2:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[C2]]
126 ; CHECK: G_BRCOND [[ICMP2]](s1), %bb.5
127 ; CHECK: G_BR %bb.8
128 ; CHECK: bb.8.entry:
129 ; CHECK: successors: %bb.5(0x80000000)
130 ; CHECK: G_BR %bb.5
131 ; CHECK: bb.2.odd:
132 ; CHECK: successors:
133 ; CHECK: bb.3.next:
134 ; CHECK: successors: %bb.5(0x80000000)
135 ; CHECK: G_BR %bb.5
136 ; CHECK: bb.4.other:
137 ; CHECK: $w0 = COPY [[DEF]](s32)
138 ; CHECK: RET_ReallyLR implicit $w0
139 ; CHECK: bb.5.phi.block:
140 ; CHECK: [[PHI:%[0-9]+]]:_(s32) = G_PHI [[C]](s32), %bb.7, [[C]](s32), %bb.8, [[C4]](s32), %bb.3
141 ; CHECK: $w0 = COPY [[C3]](s32)
142 ; CHECK: RET_ReallyLR implicit $w0
143 entry:
144 switch i32 %in, label %odd [i32 1, label %next
145 i32 57, label %other
146 i32 128, label %phi.block
147 i32 256, label %phi.block]
148 odd:
149 unreachable
150
151 next:
152 br label %phi.block
153
154 other:
155 ret i32 undef
156
157 phi.block:
158 %res = phi i32 [1, %entry], [1, %entry], [42, %next]
159 ret i32 12
160 }
161
162 define i32 @jt_test(i32 %x) {
163 ; CHECK-LABEL: name: jt_test
164 ; CHECK: bb.1.entry:
165 ; CHECK: successors: %bb.4(0x40000000), %bb.5(0x40000000)
166 ; CHECK: liveins: $w0
167 ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
168 ; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 71
169 ; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
170 ; CHECK: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 42
171 ; CHECK: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
172 ; CHECK: [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
173 ; CHECK: [[SUB:%[0-9]+]]:_(s32) = G_SUB [[COPY]], [[C4]]
174 ; CHECK: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[SUB]](s32)
175 ; CHECK: [[ZEXT1:%[0-9]+]]:_(s64) = G_ZEXT [[C]](s32)
176 ; CHECK: [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(ugt), [[ZEXT]](s64), [[ZEXT1]]
177 ; CHECK: G_BRCOND [[ICMP]](s1), %bb.4
178 ; CHECK: bb.5.entry:
179 ; CHECK: successors: %bb.3(0x2aaaaaab), %bb.4(0x2aaaaaab), %bb.2(0x2aaaaaab)
180 ; CHECK: [[JUMP_TABLE:%[0-9]+]]:_(p0) = G_JUMP_TABLE %jump-table.0
181 ; CHECK: G_BRJT [[JUMP_TABLE]](p0), %jump-table.0, [[ZEXT]](s64)
182 ; CHECK: bb.2.sw.bb:
183 ; CHECK: successors: %bb.4(0x80000000)
184 ; CHECK: %11:_(s32) = nsw G_ADD [[COPY]], [[C2]]
185 ; CHECK: G_BR %bb.4
186 ; CHECK: bb.3.sw.bb1:
187 ; CHECK: successors: %bb.4(0x80000000)
188 ; CHECK: %9:_(s32) = nsw G_MUL [[COPY]], [[C1]]
189 ; CHECK: bb.4.return:
190 ; CHECK: [[PHI:%[0-9]+]]:_(s32) = G_PHI %9(s32), %bb.3, %11(s32), %bb.2, [[C3]](s32), %bb.1, [[C3]](s32), %bb.5
191 ; CHECK: $w0 = COPY [[PHI]](s32)
192 ; CHECK: RET_ReallyLR implicit $w0
193 entry:
194 switch i32 %x, label %return [
195 i32 75, label %sw.bb
196 i32 34, label %sw.bb
197 i32 56, label %sw.bb
198 i32 35, label %sw.bb
199 i32 40, label %sw.bb
200 i32 4, label %sw.bb1
201 i32 5, label %sw.bb1
202 i32 6, label %sw.bb1
203 ]
204
205 sw.bb:
206 %add = add nsw i32 %x, 42
207 br label %return
208
209 sw.bb1:
210 %mul = mul nsw i32 %x, 3
211 br label %return
212
213 return:
214 %retval.0 = phi i32 [ %mul, %sw.bb1 ], [ %add, %sw.bb ], [ 0, %entry ]
215 ret i32 %retval.0
216 }
217
218 define i32 @range_test(i32 %x) {
219 ; CHECK-LABEL: name: range_test
220 ; CHECK: bb.1.entry:
221 ; CHECK: successors: %bb.3(0x40000000), %bb.5(0x40000000)
222 ; CHECK: liveins: $w0
223 ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
224 ; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 6
225 ; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 24
226 ; CHECK: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
227 ; CHECK: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 42
228 ; CHECK: [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
229 ; CHECK: [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[C]]
230 ; CHECK: G_BRCOND [[ICMP]](s1), %bb.3
231 ; CHECK: G_BR %bb.5
232 ; CHECK: bb.5.entry:
233 ; CHECK: successors: %bb.2(0x40000000), %bb.4(0x40000000)
234 ; CHECK: [[SUB:%[0-9]+]]:_(s32) = G_SUB [[COPY]], [[C1]]
235 ; CHECK: [[C5:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
236 ; CHECK: [[ICMP1:%[0-9]+]]:_(s1) = G_ICMP intpred(ule), [[SUB]](s32), [[C5]]
237 ; CHECK: [[C6:%[0-9]+]]:_(s1) = G_CONSTANT i1 true
238 ; CHECK: [[XOR:%[0-9]+]]:_(s1) = G_XOR [[ICMP1]], [[C6]]
239 ; CHECK: G_BRCOND [[XOR]](s1), %bb.4
240 ; CHECK: G_BR %bb.2
241 ; CHECK: bb.2.sw.bb:
242 ; CHECK: successors: %bb.4(0x80000000)
243 ; CHECK: %12:_(s32) = nsw G_ADD [[COPY]], [[C3]]
244 ; CHECK: G_BR %bb.4
245 ; CHECK: bb.3.sw.bb1:
246 ; CHECK: successors: %bb.4(0x80000000)
247 ; CHECK: %10:_(s32) = nsw G_MUL [[COPY]], [[C2]]
248 ; CHECK: bb.4.return:
249 ; CHECK: [[PHI:%[0-9]+]]:_(s32) = G_PHI %10(s32), %bb.3, %12(s32), %bb.2, [[C4]](s32), %bb.5
250 ; CHECK: $w0 = COPY [[PHI]](s32)
251 ; CHECK: RET_ReallyLR implicit $w0
252 entry:
253 switch i32 %x, label %return [
254 i32 24, label %sw.bb
255 i32 25, label %sw.bb
256 i32 26, label %sw.bb
257 i32 6, label %sw.bb1
258 ]
259
260 sw.bb:
261 %add = add nsw i32 %x, 42
262 br label %return
263
264 sw.bb1:
265 %mul = mul nsw i32 %x, 3
266 br label %return
267
268 return:
269 %retval.0 = phi i32 [ %mul, %sw.bb1 ], [ %add, %sw.bb ], [ 0, %entry ]
270 ret i32 %retval.0
271 }
272
126126 ret void
127127 false:
128128 ret void
129 }
130
131 ; Tests for switch.
132 ; This gets lowered to a very straightforward sequence of comparisons for now.
133 ; CHECK-LABEL: name: switch
134 ; CHECK: body:
135 ;
136 ; CHECK: bb.{{[a-zA-Z0-9.]+}}:
137 ; CHECK-NEXT: successors: %[[BB_CASE100:bb.[0-9]+]](0x40000000), %[[BB_NOTCASE100_CHECKNEXT:bb.[0-9]+]](0x40000000)
138 ; CHECK: %0:_(s32) = COPY $w0
139 ; CHECK: %[[reg100:[0-9]+]]:_(s32) = G_CONSTANT i32 100
140 ; CHECK: %[[reg200:[0-9]+]]:_(s32) = G_CONSTANT i32 200
141 ; CHECK: %[[reg2:[0-9]+]]:_(s32) = G_CONSTANT i32 2
142 ; CHECK: %[[reg1:[0-9]+]]:_(s32) = G_CONSTANT i32 1
143 ; CHECK: %[[reg0:[0-9]+]]:_(s32) = G_CONSTANT i32 0
144 ; CHECK: %[[regicmp100:[0-9]+]]:_(s1) = G_ICMP intpred(eq), %[[reg100]](s32), %0
145 ; CHECK: G_BRCOND %[[regicmp100]](s1), %[[BB_CASE100]]
146 ; CHECK: G_BR %[[BB_NOTCASE100_CHECKNEXT]]
147 ;
148 ; CHECK: [[BB_NOTCASE100_CHECKNEXT]].{{[a-zA-Z0-9.]+}}:
149 ; CHECK-NEXT: successors: %[[BB_CASE200:bb.[0-9]+]](0x40000000), %[[BB_NOTCASE200_CHECKNEXT:bb.[0-9]+]](0x40000000)
150 ; CHECK: %[[regicmp200:[0-9]+]]:_(s1) = G_ICMP intpred(eq), %[[reg200]](s32), %0
151 ; CHECK: G_BRCOND %[[regicmp200]](s1), %[[BB_CASE200]]
152 ; CHECK: G_BR %[[BB_NOTCASE200_CHECKNEXT]]
153 ;
154 ; CHECK: [[BB_NOTCASE200_CHECKNEXT]].{{[a-zA-Z0-9.]+}}:
155 ; CHECK-NEXT: successors: %[[BB_DEFAULT:bb.[0-9]+]](0x80000000)
156 ; CHECK: G_BR %[[BB_DEFAULT]]
157 ;
158 ; CHECK: [[BB_DEFAULT]].{{[a-zA-Z0-9.]+}}:
159 ; CHECK-NEXT: successors: %[[BB_RET:bb.[0-9]+]](0x80000000)
160 ; CHECK: %[[regretdefault:[0-9]+]]:_(s32) = G_ADD %0, %[[reg0]]
161 ; CHECK: G_BR %[[BB_RET]]
162 ;
163 ; CHECK: [[BB_CASE100]].{{[a-zA-Z0-9.]+}}:
164 ; CHECK-NEXT: successors: %[[BB_RET:bb.[0-9]+]](0x80000000)
165 ; CHECK: %[[regretc100:[0-9]+]]:_(s32) = G_ADD %0, %[[reg1]]
166 ; CHECK: G_BR %[[BB_RET]]
167 ;
168 ; CHECK: [[BB_CASE200]].{{[a-zA-Z0-9.]+}}:
169 ; CHECK-NEXT: successors: %[[BB_RET]](0x80000000)
170 ; CHECK: %[[regretc200:[0-9]+]]:_(s32) = G_ADD %0, %[[reg2]]
171 ;
172 ; CHECK: [[BB_RET]].{{[a-zA-Z0-9.]+}}:
173 ; CHECK-NEXT: %[[regret:[0-9]+]]:_(s32) = G_PHI %[[regretdefault]](s32), %[[BB_DEFAULT]], %[[regretc100]](s32), %[[BB_CASE100]]
174 ; CHECK: $w0 = COPY %[[regret]](s32)
175 ; CHECK: RET_ReallyLR implicit $w0
176 ;
177 define i32 @switch(i32 %argc) {
178 entry:
179 switch i32 %argc, label %default [
180 i32 100, label %case100
181 i32 200, label %case200
182 ]
183
184 default:
185 %tmp0 = add i32 %argc, 0
186 br label %return
187
188 case100:
189 %tmp1 = add i32 %argc, 1
190 br label %return
191
192 case200:
193 %tmp2 = add i32 %argc, 2
194 br label %return
195
196 return:
197 %res = phi i32 [ %tmp0, %default ], [ %tmp1, %case100 ], [ %tmp2, %case200 ]
198 ret i32 %res
199 }
200
201 ; The switch lowering code changes the CFG, which means that the original
202 ; %entry block is no longer a predecessor for the phi instruction. We need to
203 ; use the correct lowered MachineBasicBlock instead.
204 ; CHECK-LABEL: name: test_cfg_remap
205 ; CHECK: bb.{{[0-9]+.[a-zA-Z0-9.]+}}:
206 ; CHECK-NEXT: successors: %{{bb.[0-9]+}}(0x40000000), %[[NOTCASE1_BLOCK:bb.[0-9]+]](0x40000000)
207 ; CHECK: [[NOTCASE1_BLOCK]].{{[a-zA-Z0-9.]+}}:
208 ; CHECK-NEXT: successors: %{{bb.[0-9]+}}(0x40000000), %[[NOTCASE57_BLOCK:bb.[0-9]+]](0x40000000)
209 ; CHECK: [[NOTCASE57_BLOCK]].{{[a-zA-Z0-9.]+}}:
210 ; CHECK-NEXT: successors: %[[PHI_BLOCK:bb.[0-9]+]](0x80000000)
211 ; CHECK: G_BR %[[PHI_BLOCK]]
212 ;
213 ; CHECK: [[PHI_BLOCK]].{{[a-zA-Z0-9.]+}}:
214 ; CHECK-NEXT: G_PHI %{{.*}}(s32), %[[NOTCASE57_BLOCK:bb.[0-9]+]], %{{.*}}(s32),
215 ;
216 define i32 @test_cfg_remap(i32 %in) {
217 entry:
218 switch i32 %in, label %phi.block [i32 1, label %next
219 i32 57, label %other]
220
221 next:
222 br label %phi.block
223
224 other:
225 ret i32 undef
226
227 phi.block:
228 %res = phi i32 [1, %entry], [42, %next]
229 ret i32 %res
230 }
231
232 ; CHECK-LABEL: name: test_cfg_remap_multiple_preds
233 ; CHECK: G_PHI [[ENTRY:%.*]](s32), %bb.{{[0-9]+}}, [[ENTRY]](s32), %bb.{{[0-9]+}}
234 define i32 @test_cfg_remap_multiple_preds(i32 %in) {
235 entry:
236 switch i32 %in, label %odd [i32 1, label %next
237 i32 57, label %other
238 i32 128, label %phi.block
239 i32 256, label %phi.block]
240 odd:
241 unreachable
242
243 next:
244 br label %phi.block
245
246 other:
247 ret i32 undef
248
249 phi.block:
250 %res = phi i32 [1, %entry], [1, %entry], [42, %next]
251 ret i32 12
252129 }
253130
254131 ; Tests for indirect br.