@@ -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 (unsigned DstReg, unsigned SrcReg, MachineInstr &I,
124129 MachineRegisterInfo &MRI, MachineFunction &MF) const ;
@@ -445,6 +450,17 @@ 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+ bool Isload = (Opc == TargetOpcode::G_LOAD);
457+ if (Ty == LLT::pointer (0 , 32 ) && X86::GPRRegBankID == RB.getID ())
458+ return Isload ? X86::MOV32rm : X86::MOV32mr;
459+ if (Ty == LLT::pointer (0 , 64 ) && X86::GPRRegBankID == RB.getID ())
460+ return Isload ? X86::MOV64rm : X86::MOV64mr;
461+ return Opc;
462+ }
463+
448464unsigned X86InstructionSelector::getLoadStoreOp (const LLT &Ty,
449465 const RegisterBank &RB,
450466 unsigned Opc,
@@ -460,7 +476,7 @@ unsigned X86InstructionSelector::getLoadStoreOp(const LLT &Ty,
460476 } else if (Ty == LLT::scalar (16 )) {
461477 if (X86::GPRRegBankID == RB.getID ())
462478 return Isload ? X86::MOV16rm : X86::MOV16mr;
463- } else if (Ty == LLT::scalar (32 ) || Ty == LLT::pointer ( 0 , 32 ) ) {
479+ } else if (Ty == LLT::scalar (32 )) {
464480 if (X86::GPRRegBankID == RB.getID ())
465481 return Isload ? X86::MOV32rm : X86::MOV32mr;
466482 if (X86::VECRRegBankID == RB.getID ())
@@ -472,7 +488,7 @@ unsigned X86InstructionSelector::getLoadStoreOp(const LLT &Ty,
472488 X86::MOVSSmr);
473489 if (X86::PSRRegBankID == RB.getID ())
474490 return Isload ? X86::LD_Fp32m : X86::ST_Fp32m;
475- } else if (Ty == LLT::scalar (64 ) || Ty == LLT::pointer ( 0 , 64 ) ) {
491+ } else if (Ty == LLT::scalar (64 )) {
476492 if (X86::GPRRegBankID == RB.getID ())
477493 return Isload ? X86::MOV64rm : X86::MOV64mr;
478494 if (X86::VECRRegBankID == RB.getID ())
@@ -530,30 +546,75 @@ unsigned X86InstructionSelector::getLoadStoreOp(const LLT &Ty,
530546}
531547
532548// Fill in an address from the given instruction.
533- static void X86SelectAddress (const MachineInstr &I,
549+ static bool X86SelectAddress (MachineInstr &I, const X86TargetMachine &TM ,
534550 const MachineRegisterInfo &MRI,
535- X86AddressMode &AM) {
536- assert (I.getOperand (0 ).isReg () && " unsupported opperand ." );
551+ const X86Subtarget &STI, X86AddressMode &AM) {
552+ assert (I.getOperand (0 ).isReg () && " unsupported operand ." );
537553 assert (MRI.getType (I.getOperand (0 ).getReg ()).isPointer () &&
538554 " unsupported type." );
539555
540- if (I.getOpcode () == TargetOpcode::G_PTR_ADD) {
556+ switch (I.getOpcode ()) {
557+ default :
558+ break ;
559+ case TargetOpcode::G_FRAME_INDEX:
560+ AM.Base .FrameIndex = I.getOperand (1 ).getIndex ();
561+ AM.BaseType = X86AddressMode::FrameIndexBase;
562+ return true ;
563+ case TargetOpcode::G_PTR_ADD: {
541564 if (auto COff = getIConstantVRegSExtVal (I.getOperand (2 ).getReg (), MRI)) {
542565 int64_t Imm = *COff;
543566 if (isInt<32 >(Imm)) { // Check for displacement overflow.
544567 AM.Disp = static_cast <int32_t >(Imm);
545568 AM.Base .Reg = I.getOperand (1 ).getReg ();
546- return ;
569+ return true ;
547570 }
548571 }
549- } else if (I.getOpcode () == TargetOpcode::G_FRAME_INDEX) {
550- AM.Base .FrameIndex = I.getOperand (1 ).getIndex ();
551- AM.BaseType = X86AddressMode::FrameIndexBase;
552- return ;
572+ break ;
553573 }
574+ case TargetOpcode::G_GLOBAL_VALUE: {
575+ auto GV = I.getOperand (1 ).getGlobal ();
576+ if (GV->isThreadLocal ()) {
577+ return false ; // TODO: we don't support TLS yet.
578+ }
579+ // Can't handle alternate code models yet.
580+ if (TM.getCodeModel () != CodeModel::Small)
581+ return false ;
582+ AM.GV = GV;
583+ AM.GVOpFlags = STI.classifyGlobalReference (GV);
584+
585+ // TODO: The ABI requires an extra load. not supported yet.
586+ if (isGlobalStubReference (AM.GVOpFlags ))
587+ return false ;
554588
589+ // TODO: This reference is relative to the pic base. not supported yet.
590+ if (isGlobalRelativeToPICBase (AM.GVOpFlags ))
591+ return false ;
592+
593+ if (STI.isPICStyleRIPRel ()) {
594+ // Use rip-relative addressing.
595+ assert (AM.Base .Reg == 0 && AM.IndexReg == 0 );
596+ AM.Base .Reg = X86::RIP;
597+ }
598+ return true ;
599+ }
600+ case TargetOpcode::G_CONSTANT_POOL: {
601+ // TODO: Need a separate move for Large model
602+ if (TM.getCodeModel () == CodeModel::Large)
603+ return false ;
604+
605+ AM.GVOpFlags = STI.classifyLocalReference (nullptr );
606+ if (AM.GVOpFlags == X86II::MO_GOTOFF)
607+ AM.Base .Reg = STI.getInstrInfo ()->getGlobalBaseReg (I.getMF ());
608+ else if (STI.is64Bit ())
609+ AM.Base .Reg = X86::RIP;
610+ AM.CP = true ;
611+ AM.Disp = I.getOperand (1 ).getIndex ();
612+ return true ;
613+ }
614+ }
555615 // Default behavior.
556616 AM.Base .Reg = I.getOperand (0 ).getReg ();
617+ return true ;
557618}
558619
559620bool X86InstructionSelector::selectLoadStoreOp (MachineInstr &I,
@@ -586,36 +647,18 @@ bool X86InstructionSelector::selectLoadStoreOp(MachineInstr &I,
586647 }
587648 }
588649
589- unsigned NewOpc = getLoadStoreOp (Ty, RB, Opc, MemOp. getAlign () );
650+ unsigned NewOpc = getPtrLoadStoreOp (Ty, RB, Opc);
590651 if (NewOpc == Opc)
591652 return false ;
592653
593654 I.setDesc (TII.get (NewOpc));
594655 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- unsigned PICBase = 0 ;
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- }
656+ MachineInstr *Ptr = MRI.getVRegDef (I.getOperand (1 ).getReg ());
616657
617658 X86AddressMode AM;
618- X86SelectAddress (*Ptr, MRI, AM);
659+ if (!X86SelectAddress (*Ptr, TM, MRI, STI, AM))
660+ return false ;
661+
619662 if (Opc == TargetOpcode::G_LOAD) {
620663 I.removeOperand (1 );
621664 addFullAddress (MIB, AM);
@@ -673,33 +716,10 @@ bool X86InstructionSelector::selectGlobalValue(MachineInstr &I,
673716 assert ((I.getOpcode () == TargetOpcode::G_GLOBAL_VALUE) &&
674717 " unexpected instruction" );
675718
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-
685719 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 ))
720+ if (!X86SelectAddress (I, TM, MRI, STI, AM))
691721 return false ;
692722
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-
703723 const Register DefReg = I.getOperand (0 ).getReg ();
704724 LLT Ty = MRI.getType (DefReg);
705725 unsigned NewOpc = getLeaOP (Ty, STI);
@@ -1880,6 +1900,49 @@ bool X86InstructionSelector::selectSelect(MachineInstr &I,
18801900 return true ;
18811901}
18821902
1903+ InstructionSelector::ComplexRendererFns
1904+ X86InstructionSelector::selectAddr (MachineOperand &Root) const {
1905+ MachineInstr *MI = Root.getParent ();
1906+ MachineIRBuilder MIRBuilder (*MI);
1907+
1908+ MachineRegisterInfo &MRI = MI->getMF ()->getRegInfo ();
1909+ MachineInstr *Ptr = MRI.getVRegDef (Root.getReg ());
1910+ X86AddressMode AM;
1911+ X86SelectAddress (*Ptr, TM, MRI, STI, AM);
1912+
1913+ if (AM.Scale != 1 )
1914+ return std::nullopt ;
1915+
1916+ if (AM.IndexReg )
1917+ return std::nullopt ;
1918+
1919+ return {// Base
1920+ {[=](MachineInstrBuilder &MIB) {
1921+ if (AM.BaseType == X86AddressMode::RegBase)
1922+ MIB.addUse (AM.Base .Reg );
1923+ else {
1924+ assert (AM.BaseType == X86AddressMode::FrameIndexBase &&
1925+ " Unknown type of address base" );
1926+ MIB.addFrameIndex (AM.Base .FrameIndex );
1927+ }
1928+ },
1929+ // Scale
1930+ [=](MachineInstrBuilder &MIB) { MIB.addImm (AM.Scale ); },
1931+ // Index
1932+ [=](MachineInstrBuilder &MIB) { MIB.addUse (0 ); },
1933+ // Disp
1934+ [=](MachineInstrBuilder &MIB) {
1935+ if (AM.GV )
1936+ MIB.addGlobalAddress (AM.GV , AM.Disp , AM.GVOpFlags );
1937+ else if (AM.CP )
1938+ MIB.addConstantPoolIndex (AM.Disp , 0 , AM.GVOpFlags );
1939+ else
1940+ MIB.addImm (AM.Disp );
1941+ },
1942+ // Segment
1943+ [=](MachineInstrBuilder &MIB) { MIB.addUse (0 ); }}};
1944+ }
1945+
18831946InstructionSelector *
18841947llvm::createX86InstructionSelector (const X86TargetMachine &TM,
18851948 const X86Subtarget &Subtarget,
0 commit comments