@@ -2123,7 +2123,8 @@ void SelectionDAGBuilder::CopyToExportRegsIfNeeded(const Value *V) {
2123
2123
2124
2124
DenseMap<const Value *, Register>::iterator VMI = FuncInfo.ValueMap .find (V);
2125
2125
if (VMI != FuncInfo.ValueMap .end ()) {
2126
- assert (!V->use_empty () && " Unused value assigned virtual registers!" );
2126
+ assert ((!V->use_empty () || isa<CallBrInst>(V)) &&
2127
+ " Unused value assigned virtual registers!" );
2127
2128
CopyValueToVirtualRegister (V, VMI->second );
2128
2129
}
2129
2130
}
@@ -7317,6 +7318,9 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
7317
7318
case Intrinsic::experimental_vector_splice:
7318
7319
visitVectorSplice (I);
7319
7320
return ;
7321
+ case Intrinsic::callbr_landingpad:
7322
+ visitCallBrLandingPad (I);
7323
+ return ;
7320
7324
}
7321
7325
}
7322
7326
@@ -11592,3 +11596,113 @@ void SelectionDAGBuilder::visitVectorSplice(const CallInst &I) {
11592
11596
Mask.push_back (Idx + i);
11593
11597
setValue (&I, DAG.getVectorShuffle (VT, DL, V1, V2, Mask));
11594
11598
}
11599
+
11600
+ // Consider the following MIR after SelectionDAG, which produces output in
11601
+ // phyregs in the first case or virtregs in the second case.
11602
+ //
11603
+ // INLINEASM_BR ..., implicit-def $ebx, ..., implicit-def $edx
11604
+ // %5:gr32 = COPY $ebx
11605
+ // %6:gr32 = COPY $edx
11606
+ // %1:gr32 = COPY %6:gr32
11607
+ // %0:gr32 = COPY %5:gr32
11608
+ //
11609
+ // INLINEASM_BR ..., def %5:gr32, ..., def %6:gr32
11610
+ // %1:gr32 = COPY %6:gr32
11611
+ // %0:gr32 = COPY %5:gr32
11612
+ //
11613
+ // Given %0, we'd like to return $ebx in the first case and %5 in the second.
11614
+ // Given %1, we'd like to return $edx in the first case and %6 in the second.
11615
+ //
11616
+ // If a callbr has outputs, it will have a single mapping in FuncInfo.ValueMap
11617
+ // to a single virtreg (such as %0). The remaining outputs monotonically
11618
+ // increase in virtreg number from there. If a callbr has no outputs, then it
11619
+ // should not have a corresponding callbr landingpad; in fact, the callbr
11620
+ // landingpad would not even be able to refer to such a callbr.
11621
+ static Register FollowCopyChain (MachineRegisterInfo &MRI, Register Reg) {
11622
+ MachineInstr *MI = MRI.def_begin (Reg)->getParent ();
11623
+ // There is definitely at least one copy.
11624
+ assert (MI->getOpcode () == TargetOpcode::COPY &&
11625
+ " start of copy chain MUST be COPY" );
11626
+ Reg = MI->getOperand (1 ).getReg ();
11627
+ MI = MRI.def_begin (Reg)->getParent ();
11628
+ // There may be an optional second copy.
11629
+ if (MI->getOpcode () == TargetOpcode::COPY) {
11630
+ assert (Reg.isVirtual () && " expected COPY of virtual register" );
11631
+ Reg = MI->getOperand (1 ).getReg ();
11632
+ assert (Reg.isPhysical () && " expected COPY of physical register" );
11633
+ MI = MRI.def_begin (Reg)->getParent ();
11634
+ }
11635
+ // The start of the chain must be an INLINEASM_BR.
11636
+ assert (MI->getOpcode () == TargetOpcode::INLINEASM_BR &&
11637
+ " end of copy chain MUST be INLINEASM_BR" );
11638
+ return Reg;
11639
+ }
11640
+
11641
+ // We must do this walk rather than the simpler
11642
+ // setValue(&I, getCopyFromRegs(CBR, CBR->getType()));
11643
+ // otherwise we will end up with copies of virtregs only valid along direct
11644
+ // edges.
11645
+ void SelectionDAGBuilder::visitCallBrLandingPad (const CallInst &I) {
11646
+ SmallVector<EVT, 8 > ResultVTs;
11647
+ SmallVector<SDValue, 8 > ResultValues;
11648
+ const auto *CBR =
11649
+ cast<CallBrInst>(I.getParent ()->getUniquePredecessor ()->getTerminator ());
11650
+
11651
+ const TargetLowering &TLI = DAG.getTargetLoweringInfo ();
11652
+ const TargetRegisterInfo *TRI = DAG.getSubtarget ().getRegisterInfo ();
11653
+ MachineRegisterInfo &MRI = DAG.getMachineFunction ().getRegInfo ();
11654
+
11655
+ unsigned InitialDef = FuncInfo.ValueMap [CBR];
11656
+ SDValue Chain = DAG.getRoot ();
11657
+
11658
+ // Re-parse the asm constraints string.
11659
+ TargetLowering::AsmOperandInfoVector TargetConstraints =
11660
+ TLI.ParseConstraints (DAG.getDataLayout (), TRI, *CBR);
11661
+ for (auto &T : TargetConstraints) {
11662
+ SDISelAsmOperandInfo OpInfo (T);
11663
+ if (OpInfo.Type != InlineAsm::isOutput)
11664
+ continue ;
11665
+
11666
+ // Pencil in OpInfo.ConstraintType and OpInfo.ConstraintVT based on the
11667
+ // individual constraint.
11668
+ TLI.ComputeConstraintToUse (OpInfo, OpInfo.CallOperand , &DAG);
11669
+
11670
+ switch (OpInfo.ConstraintType ) {
11671
+ case TargetLowering::C_Register:
11672
+ case TargetLowering::C_RegisterClass: {
11673
+ // Fill in OpInfo.AssignedRegs.Regs.
11674
+ getRegistersForValue (DAG, getCurSDLoc (), OpInfo, OpInfo);
11675
+
11676
+ // getRegistersForValue may produce 1 to many registers based on whether
11677
+ // the OpInfo.ConstraintVT is legal on the target or not.
11678
+ for (size_t i = 0 , e = OpInfo.AssignedRegs .Regs .size (); i != e; ++i) {
11679
+ Register OriginalDef = FollowCopyChain (MRI, InitialDef++);
11680
+ if (Register::isPhysicalRegister (OriginalDef))
11681
+ FuncInfo.MBB ->addLiveIn (OriginalDef);
11682
+ // Update the assigned registers to use the original defs.
11683
+ OpInfo.AssignedRegs .Regs [i] = OriginalDef;
11684
+ }
11685
+
11686
+ SDValue V = OpInfo.AssignedRegs .getCopyFromRegs (
11687
+ DAG, FuncInfo, getCurSDLoc (), Chain, nullptr , CBR);
11688
+ ResultValues.push_back (V);
11689
+ ResultVTs.push_back (OpInfo.ConstraintVT );
11690
+ break ;
11691
+ }
11692
+ case TargetLowering::C_Other: {
11693
+ SDValue Flag;
11694
+ SDValue V = TLI.LowerAsmOutputForConstraint (Chain, Flag, getCurSDLoc (),
11695
+ OpInfo, DAG);
11696
+ ++InitialDef;
11697
+ ResultValues.push_back (V);
11698
+ ResultVTs.push_back (OpInfo.ConstraintVT );
11699
+ break ;
11700
+ }
11701
+ default :
11702
+ break ;
11703
+ }
11704
+ }
11705
+ SDValue V = DAG.getNode (ISD::MERGE_VALUES, getCurSDLoc (),
11706
+ DAG.getVTList (ResultVTs), ResultValues);
11707
+ setValue (&I, V);
11708
+ }
0 commit comments