@@ -73,6 +73,9 @@ class X86InstructionSelector : public InstructionSelector {
7373 // TODO: remove after supported by Tablegen-erated instruction selection.
7474 unsigned getLoadStoreOp (const LLT &Ty, const RegisterBank &RB, unsigned Opc,
7575 Align Alignment) const ;
76+ // TODO: remove once p0<->i32/i64 matching is available
77+ unsigned getPtrLoadStoreOp (const LLT &Ty, const RegisterBank &RB,
78+ unsigned Opc) const ;
7679
7780 bool selectLoadStoreOp (MachineInstr &I, MachineRegisterInfo &MRI,
7881 MachineFunction &MF) const ;
@@ -119,6 +122,8 @@ class X86InstructionSelector : public InstructionSelector {
119122 bool selectSelect (MachineInstr &I, MachineRegisterInfo &MRI,
120123 MachineFunction &MF) const ;
121124
125+ ComplexRendererFns selectAddr (MachineOperand &Root) const ;
126+
122127 // emit insert subreg instruction and insert it before MachineInstr &I
123128 bool emitInsertSubreg (Register DstReg, Register SrcReg, MachineInstr &I,
124129 MachineRegisterInfo &MRI, MachineFunction &MF) const ;
@@ -445,6 +450,25 @@ bool X86InstructionSelector::select(MachineInstr &I) {
445450 return false ;
446451}
447452
453+ unsigned X86InstructionSelector::getPtrLoadStoreOp (const LLT &Ty,
454+ const RegisterBank &RB,
455+ unsigned Opc) const {
456+ assert ((Opc == TargetOpcode::G_STORE || Opc == TargetOpcode::G_LOAD) &&
457+ " Only G_STORE and G_LOAD are expected for selection" );
458+ if (Ty.isPointer () && X86::GPRRegBankID == RB.getID ()) {
459+ bool IsLoad = (Opc == TargetOpcode::G_LOAD);
460+ switch (Ty.getSizeInBits ()) {
461+ default :
462+ break ;
463+ case 32 :
464+ return IsLoad ? X86::MOV32rm : X86::MOV32mr;
465+ case 64 :
466+ return IsLoad ? X86::MOV64rm : X86::MOV64mr;
467+ }
468+ }
469+ return Opc;
470+ }
471+
448472unsigned X86InstructionSelector::getLoadStoreOp (const LLT &Ty,
449473 const RegisterBank &RB,
450474 unsigned Opc,
@@ -460,7 +484,7 @@ unsigned X86InstructionSelector::getLoadStoreOp(const LLT &Ty,
460484 } else if (Ty == LLT::scalar (16 )) {
461485 if (X86::GPRRegBankID == RB.getID ())
462486 return Isload ? X86::MOV16rm : X86::MOV16mr;
463- } else if (Ty == LLT::scalar (32 ) || Ty == LLT::pointer ( 0 , 32 ) ) {
487+ } else if (Ty == LLT::scalar (32 )) {
464488 if (X86::GPRRegBankID == RB.getID ())
465489 return Isload ? X86::MOV32rm : X86::MOV32mr;
466490 if (X86::VECRRegBankID == RB.getID ())
@@ -472,7 +496,7 @@ unsigned X86InstructionSelector::getLoadStoreOp(const LLT &Ty,
472496 X86::MOVSSmr);
473497 if (X86::PSRRegBankID == RB.getID ())
474498 return Isload ? X86::LD_Fp32m : X86::ST_Fp32m;
475- } else if (Ty == LLT::scalar (64 ) || Ty == LLT::pointer ( 0 , 64 ) ) {
499+ } else if (Ty == LLT::scalar (64 )) {
476500 if (X86::GPRRegBankID == RB.getID ())
477501 return Isload ? X86::MOV64rm : X86::MOV64mr;
478502 if (X86::VECRRegBankID == RB.getID ())
@@ -530,30 +554,76 @@ unsigned X86InstructionSelector::getLoadStoreOp(const LLT &Ty,
530554}
531555
532556// Fill in an address from the given instruction.
533- static void X86SelectAddress (const MachineInstr &I,
557+ static bool X86SelectAddress (MachineInstr &I, const X86TargetMachine &TM ,
534558 const MachineRegisterInfo &MRI,
535- X86AddressMode &AM) {
536- assert (I.getOperand (0 ).isReg () && " unsupported opperand ." );
559+ const X86Subtarget &STI, X86AddressMode &AM) {
560+ assert (I.getOperand (0 ).isReg () && " unsupported operand ." );
537561 assert (MRI.getType (I.getOperand (0 ).getReg ()).isPointer () &&
538562 " unsupported type." );
539563
540- if (I.getOpcode () == TargetOpcode::G_PTR_ADD) {
564+ switch (I.getOpcode ()) {
565+ default :
566+ break ;
567+ case TargetOpcode::G_FRAME_INDEX:
568+ AM.Base .FrameIndex = I.getOperand (1 ).getIndex ();
569+ AM.BaseType = X86AddressMode::FrameIndexBase;
570+ return true ;
571+ case TargetOpcode::G_PTR_ADD: {
541572 if (auto COff = getIConstantVRegSExtVal (I.getOperand (2 ).getReg (), MRI)) {
542573 int64_t Imm = *COff;
543574 if (isInt<32 >(Imm)) { // Check for displacement overflow.
544575 AM.Disp = static_cast <int32_t >(Imm);
545576 AM.Base .Reg = I.getOperand (1 ).getReg ();
546- return ;
577+ return true ;
547578 }
548579 }
549- } else if (I.getOpcode () == TargetOpcode::G_FRAME_INDEX) {
550- AM.Base .FrameIndex = I.getOperand (1 ).getIndex ();
551- AM.BaseType = X86AddressMode::FrameIndexBase;
552- return ;
580+ break ;
553581 }
582+ case TargetOpcode::G_GLOBAL_VALUE: {
583+ auto GV = I.getOperand (1 ).getGlobal ();
584+ if (GV->isThreadLocal ()) {
585+ return false ; // TODO: we don't support TLS yet.
586+ }
587+ // Can't handle alternate code models yet.
588+ if (TM.getCodeModel () != CodeModel::Small)
589+ return false ;
590+ AM.GV = GV;
591+ AM.GVOpFlags = STI.classifyGlobalReference (GV);
592+
593+ // TODO: The ABI requires an extra load. not supported yet.
594+ if (isGlobalStubReference (AM.GVOpFlags ))
595+ return false ;
596+
597+ // TODO: This reference is relative to the pic base. not supported yet.
598+ if (isGlobalRelativeToPICBase (AM.GVOpFlags ))
599+ return false ;
600+
601+ if (STI.isPICStyleRIPRel ()) {
602+ // Use rip-relative addressing.
603+ assert (AM.Base .Reg == 0 && AM.IndexReg == 0 &&
604+ " RIP-relative addresses can't have additional register operands" );
605+ AM.Base .Reg = X86::RIP;
606+ }
607+ return true ;
608+ }
609+ case TargetOpcode::G_CONSTANT_POOL: {
610+ // TODO: Need a separate move for Large model
611+ if (TM.getCodeModel () == CodeModel::Large)
612+ return false ;
554613
614+ AM.GVOpFlags = STI.classifyLocalReference (nullptr );
615+ if (AM.GVOpFlags == X86II::MO_GOTOFF)
616+ AM.Base .Reg = STI.getInstrInfo ()->getGlobalBaseReg (I.getMF ());
617+ else if (STI.is64Bit ())
618+ AM.Base .Reg = X86::RIP;
619+ AM.CP = true ;
620+ AM.Disp = I.getOperand (1 ).getIndex ();
621+ return true ;
622+ }
623+ }
555624 // Default behavior.
556625 AM.Base .Reg = I.getOperand (0 ).getReg ();
626+ return true ;
557627}
558628
559629bool X86InstructionSelector::selectLoadStoreOp (MachineInstr &I,
@@ -586,36 +656,18 @@ bool X86InstructionSelector::selectLoadStoreOp(MachineInstr &I,
586656 }
587657 }
588658
589- unsigned NewOpc = getLoadStoreOp (Ty, RB, Opc, MemOp. getAlign () );
659+ unsigned NewOpc = getPtrLoadStoreOp (Ty, RB, Opc);
590660 if (NewOpc == Opc)
591661 return false ;
592662
593663 I.setDesc (TII.get (NewOpc));
594664 MachineInstrBuilder MIB (MF, I);
595- const MachineInstr *Ptr = MRI.getVRegDef (I.getOperand (1 ).getReg ());
596-
597- if (Ptr->getOpcode () == TargetOpcode::G_CONSTANT_POOL) {
598- assert (Opc == TargetOpcode::G_LOAD &&
599- " Only G_LOAD from constant pool is expected" );
600- // TODO: Need a separate move for Large model
601- if (TM.getCodeModel () == CodeModel::Large)
602- return false ;
603-
604- unsigned char OpFlag = STI.classifyLocalReference (nullptr );
605- Register PICBase;
606- if (OpFlag == X86II::MO_GOTOFF)
607- PICBase = TII.getGlobalBaseReg (&MF);
608- else if (STI.is64Bit ())
609- PICBase = X86::RIP;
610-
611- I.removeOperand (1 );
612- addConstantPoolReference (MIB, Ptr->getOperand (1 ).getIndex (), PICBase,
613- OpFlag);
614- return constrainSelectedInstRegOperands (I, TII, TRI, RBI);
615- }
665+ MachineInstr *Ptr = MRI.getVRegDef (I.getOperand (1 ).getReg ());
616666
617667 X86AddressMode AM;
618- X86SelectAddress (*Ptr, MRI, AM);
668+ if (!X86SelectAddress (*Ptr, TM, MRI, STI, AM))
669+ return false ;
670+
619671 if (Opc == TargetOpcode::G_LOAD) {
620672 I.removeOperand (1 );
621673 addFullAddress (MIB, AM);
@@ -673,33 +725,10 @@ bool X86InstructionSelector::selectGlobalValue(MachineInstr &I,
673725 assert ((I.getOpcode () == TargetOpcode::G_GLOBAL_VALUE) &&
674726 " unexpected instruction" );
675727
676- auto GV = I.getOperand (1 ).getGlobal ();
677- if (GV->isThreadLocal ()) {
678- return false ; // TODO: we don't support TLS yet.
679- }
680-
681- // Can't handle alternate code models yet.
682- if (TM.getCodeModel () != CodeModel::Small)
683- return false ;
684-
685728 X86AddressMode AM;
686- AM.GV = GV;
687- AM.GVOpFlags = STI.classifyGlobalReference (GV);
688-
689- // TODO: The ABI requires an extra load. not supported yet.
690- if (isGlobalStubReference (AM.GVOpFlags ))
729+ if (!X86SelectAddress (I, TM, MRI, STI, AM))
691730 return false ;
692731
693- // TODO: This reference is relative to the pic base. not supported yet.
694- if (isGlobalRelativeToPICBase (AM.GVOpFlags ))
695- return false ;
696-
697- if (STI.isPICStyleRIPRel ()) {
698- // Use rip-relative addressing.
699- assert (AM.Base .Reg == 0 && AM.IndexReg == 0 );
700- AM.Base .Reg = X86::RIP;
701- }
702-
703732 const Register DefReg = I.getOperand (0 ).getReg ();
704733 LLT Ty = MRI.getType (DefReg);
705734 unsigned NewOpc = getLeaOP (Ty, STI);
@@ -1880,6 +1909,46 @@ bool X86InstructionSelector::selectSelect(MachineInstr &I,
18801909 return true ;
18811910}
18821911
1912+ InstructionSelector::ComplexRendererFns
1913+ X86InstructionSelector::selectAddr (MachineOperand &Root) const {
1914+ MachineInstr *MI = Root.getParent ();
1915+ MachineIRBuilder MIRBuilder (*MI);
1916+
1917+ MachineRegisterInfo &MRI = MI->getMF ()->getRegInfo ();
1918+ MachineInstr *Ptr = MRI.getVRegDef (Root.getReg ());
1919+ X86AddressMode AM;
1920+ X86SelectAddress (*Ptr, TM, MRI, STI, AM);
1921+
1922+ if (AM.IndexReg )
1923+ return std::nullopt ;
1924+
1925+ return {// Base
1926+ {[=](MachineInstrBuilder &MIB) {
1927+ if (AM.BaseType == X86AddressMode::RegBase)
1928+ MIB.addUse (AM.Base .Reg );
1929+ else {
1930+ assert (AM.BaseType == X86AddressMode::FrameIndexBase &&
1931+ " Unknown type of address base" );
1932+ MIB.addFrameIndex (AM.Base .FrameIndex );
1933+ }
1934+ },
1935+ // Scale
1936+ [=](MachineInstrBuilder &MIB) { MIB.addImm (AM.Scale ); },
1937+ // Index
1938+ [=](MachineInstrBuilder &MIB) { MIB.addUse (0 ); },
1939+ // Disp
1940+ [=](MachineInstrBuilder &MIB) {
1941+ if (AM.GV )
1942+ MIB.addGlobalAddress (AM.GV , AM.Disp , AM.GVOpFlags );
1943+ else if (AM.CP )
1944+ MIB.addConstantPoolIndex (AM.Disp , 0 , AM.GVOpFlags );
1945+ else
1946+ MIB.addImm (AM.Disp );
1947+ },
1948+ // Segment
1949+ [=](MachineInstrBuilder &MIB) { MIB.addUse (0 ); }}};
1950+ }
1951+
18831952InstructionSelector *
18841953llvm::createX86InstructionSelector (const X86TargetMachine &TM,
18851954 const X86Subtarget &Subtarget,
0 commit comments