diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.h b/llvm/lib/Target/RISCV/RISCVISelLowering.h --- a/llvm/lib/Target/RISCV/RISCVISelLowering.h +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.h @@ -53,6 +53,9 @@ // Selected as PseudoAddTPRel. Used to emit a TP-relative relocation. ADD_TPREL, + // Load address. + LA_TLS_GD, + // Multiply high for signedxunsigned. MULHSU, // RV64I shifts, directly matching the semantics of the named RISC-V @@ -326,6 +329,10 @@ // WARNING: Do not add anything in the end unless you want the node to // have memop! In fact, starting from FIRST_TARGET_MEMORY_OPCODE all // opcodes will be thought as target memory ops! + + // Load address. + LA = ISD::FIRST_TARGET_MEMORY_OPCODE, + LA_TLS_IE, }; } // namespace RISCVISD diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -3614,15 +3614,15 @@ // Use PC-relative addressing to access the GOT for this symbol, then load // the address from the GOT. This generates the pattern (PseudoLA sym), // which expands to (ld (addi (auipc %got_pcrel_hi(sym)) %pcrel_lo(auipc))). - SDValue Load = - SDValue(DAG.getMachineNode(RISCV::PseudoLA, DL, Ty, Addr), 0); MachineFunction &MF = DAG.getMachineFunction(); MachineMemOperand *MemOp = MF.getMachineMemOperand( MachinePointerInfo::getGOT(MF), MachineMemOperand::MOLoad | MachineMemOperand::MODereferenceable | MachineMemOperand::MOInvariant, LLT(Ty.getSimpleVT()), Align(Ty.getFixedSizeInBits() / 8)); - DAG.setNodeMemRefs(cast(Load.getNode()), {MemOp}); + SDValue Load = + DAG.getMemIntrinsicNode(RISCVISD::LA, DL, DAG.getVTList(Ty, MVT::Other), + {DAG.getEntryNode(), Addr}, Ty, MemOp); return Load; } @@ -3693,15 +3693,15 @@ // the pattern (PseudoLA_TLS_IE sym), which expands to // (ld (auipc %tls_ie_pcrel_hi(sym)) %pcrel_lo(auipc)). SDValue Addr = DAG.getTargetGlobalAddress(GV, DL, Ty, 0, 0); - SDValue Load = - SDValue(DAG.getMachineNode(RISCV::PseudoLA_TLS_IE, DL, Ty, Addr), 0); MachineFunction &MF = DAG.getMachineFunction(); MachineMemOperand *MemOp = MF.getMachineMemOperand( MachinePointerInfo::getGOT(MF), MachineMemOperand::MOLoad | MachineMemOperand::MODereferenceable | MachineMemOperand::MOInvariant, LLT(Ty.getSimpleVT()), Align(Ty.getFixedSizeInBits() / 8)); - DAG.setNodeMemRefs(cast(Load.getNode()), {MemOp}); + SDValue Load = DAG.getMemIntrinsicNode( + RISCVISD::LA_TLS_IE, DL, DAG.getVTList(Ty, MVT::Other), + {DAG.getEntryNode(), Addr}, Ty, MemOp); // Add the thread pointer. SDValue TPReg = DAG.getRegister(RISCV::X4, XLenVT); @@ -3737,8 +3737,7 @@ // This generates the pattern (PseudoLA_TLS_GD sym), which expands to // (addi (auipc %tls_gd_pcrel_hi(sym)) %pcrel_lo(auipc)). SDValue Addr = DAG.getTargetGlobalAddress(GV, DL, Ty, 0, 0); - SDValue Load = - SDValue(DAG.getMachineNode(RISCV::PseudoLA_TLS_GD, DL, Ty, Addr), 0); + SDValue Load = DAG.getNode(RISCVISD::LA_TLS_GD, DL, Ty, Addr); // Prepare argument list to generate call. ArgListTy Args; @@ -11185,6 +11184,9 @@ NODE_NAME_CASE(HI) NODE_NAME_CASE(LLA) NODE_NAME_CASE(ADD_TPREL) + NODE_NAME_CASE(LA) + NODE_NAME_CASE(LA_TLS_IE) + NODE_NAME_CASE(LA_TLS_GD) NODE_NAME_CASE(MULHSU) NODE_NAME_CASE(SLLW) NODE_NAME_CASE(SRAW) diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td @@ -92,6 +92,12 @@ SDTCisSameAs<0, 3>, SDTCisInt<0>]>>; +def riscv_la : SDNode<"RISCVISD::LA", SDTLoad, + [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; +def riscv_la_tls_ie : SDNode<"RISCVISD::LA_TLS_IE", SDTLoad, + [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; +def riscv_la_tls_gd : SDNode<"RISCVISD::LA_TLS_GD", SDTIntUnaryOp>; + //===----------------------------------------------------------------------===// // Operand and SDNode transformation definitions. //===----------------------------------------------------------------------===// @@ -1400,16 +1406,23 @@ def PseudoLA : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [], "la", "$dst, $src">; +def : Pat<(riscv_la tglobaladdr:$in), (PseudoLA tglobaladdr:$in)>; + let hasSideEffects = 0, mayLoad = 1, mayStore = 0, Size = 8, isCodeGenOnly = 0, isAsmParserOnly = 1 in def PseudoLA_TLS_IE : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [], "la.tls.ie", "$dst, $src">; +def : Pat<(riscv_la_tls_ie tglobaltlsaddr:$in), + (PseudoLA_TLS_IE tglobaltlsaddr:$in)>; + let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Size = 8, isCodeGenOnly = 0, isAsmParserOnly = 1 in def PseudoLA_TLS_GD : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [], "la.tls.gd", "$dst, $src">; +def : Pat<(riscv_la_tls_gd tglobaltlsaddr:$in), + (PseudoLA_TLS_GD tglobaltlsaddr:$in)>; /// Sign/Zero Extends