Skip to content

Commit 4922ab9

Browse files
authored
[RISCV] Relax codegen predicates for HINT-based instructions (#179872)
Following the assembler/disassembler changes in #178609, this patch also relaxes the codegen predicates for HINT-based instructions. Since these instructions use encodings that are architecturally guaranteed not to trap, the compiler can safely generate them regardless of extension availability. Changes: - int_riscv_pause: Remove HasStdExtZihintpause predicate. The pause intrinsic now generates the FENCE hint encoding unconditionally. - NTL hints: Remove hasStdExtZihintntl() check in emitNTLHint(). Non-temporal locality hints are now emitted for all nontemporal memory operations.
1 parent 0704b68 commit 4922ab9

File tree

7 files changed

+537
-1300
lines changed

7 files changed

+537
-1300
lines changed

llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -273,18 +273,19 @@ bool RISCVAsmPrinter::EmitToStreamer(MCStreamer &S, const MCInst &Inst,
273273
// instructions) auto-generated.
274274
#include "RISCVGenMCPseudoLowering.inc"
275275

276-
// If the target supports Zihintntl and the instruction has a nontemporal
277-
// MachineMemOperand, emit an NTLH hint instruction before it.
276+
// If the instruction has a nontemporal MachineMemOperand, emit an NTL hint
277+
// instruction before it. NTL hints are always safe to emit since they use
278+
// HINT encodings that are guaranteed not to trap
279+
// (riscv-non-isa/riscv-elf-psabi-doc#474).
278280
void RISCVAsmPrinter::emitNTLHint(const MachineInstr *MI) {
279-
if (!STI->hasStdExtZihintntl())
281+
if (!STI->getInstrInfo()->requiresNTLHint(*MI))
280282
return;
281283

282-
if (MI->memoperands_empty())
283-
return;
284+
assert(!MI->memoperands_empty());
284285

285286
MachineMemOperand *MMO = *(MI->memoperands_begin());
286-
if (!MMO->isNonTemporal())
287-
return;
287+
288+
assert(MMO->isNonTemporal());
288289

289290
unsigned NontemporalMode = 0;
290291
if (MMO->getFlags() & MONontemporalBit0)

llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3061,6 +3061,11 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
30613061
return;
30623062
}
30633063
case ISD::PREFETCH:
3064+
// MIPS's prefetch instruction already encodes the hint within the
3065+
// instruction itself, so no extra NTL hint is needed.
3066+
if (Subtarget->hasVendorXMIPSCBOP())
3067+
break;
3068+
30643069
unsigned Locality = Node->getConstantOperandVal(3);
30653070
if (Locality > 2)
30663071
break;

llvm/lib/Target/RISCV/RISCVInstrInfo.cpp

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1994,16 +1994,13 @@ unsigned RISCVInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
19941994
*MF.getTarget().getMCAsmInfo());
19951995
}
19961996

1997-
if (!MI.memoperands_empty()) {
1998-
MachineMemOperand *MMO = *(MI.memoperands_begin());
1999-
if (STI.hasStdExtZihintntl() && MMO->isNonTemporal()) {
2000-
if (STI.hasStdExtZca()) {
2001-
if (isCompressibleInst(MI, STI))
2002-
return 4; // c.ntl.all + c.load/c.store
2003-
return 6; // c.ntl.all + load/store
2004-
}
2005-
return 8; // ntl.all + load/store
1997+
if (requiresNTLHint(MI)) {
1998+
if (STI.hasStdExtZca()) {
1999+
if (isCompressibleInst(MI, STI))
2000+
return 4; // c.ntl.all + c.load/c.store
2001+
return 6; // c.ntl.all + load/store
20062002
}
2003+
return 8; // ntl.all + load/store
20072004
}
20082005

20092006
if (Opcode == TargetOpcode::BUNDLE)
@@ -5326,3 +5323,14 @@ bool RISCVInstrInfo::isVRegCopy(const MachineInstr *MI, unsigned LMul) const {
53265323
RISCVVType::decodeVLMUL(RISCVRI::getLMul(RC->TSFlags));
53275324
return (!RCFractional && LMul == RCLMul) || (RCFractional && LMul == 1);
53285325
}
5326+
5327+
bool RISCVInstrInfo::requiresNTLHint(const MachineInstr &MI) const {
5328+
if (MI.memoperands_empty())
5329+
return false;
5330+
5331+
MachineMemOperand *MMO = *(MI.memoperands_begin());
5332+
if (!MMO->isNonTemporal())
5333+
return false;
5334+
5335+
return true;
5336+
}

llvm/lib/Target/RISCV/RISCVInstrInfo.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,9 @@ class RISCVInstrInfo : public RISCVGenInstrInfo {
330330
/// or any kind of vector registers when \p LMul is zero.
331331
bool isVRegCopy(const MachineInstr *MI, unsigned LMul = 0) const;
332332

333+
/// Return true if the instruction requires an NTL hint to be emitted.
334+
bool requiresNTLHint(const MachineInstr &MI) const;
335+
333336
/// Return true if pairing the given load or store may be paired with another.
334337
static bool isPairableLdStInstOpc(unsigned Opc);
335338

llvm/lib/Target/RISCV/RISCVInstrInfo.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2316,8 +2316,8 @@ def : Pat<(i64 (add GPR:$rs1, negImm:$rs2)), (SUB GPR:$rs1, negImm:$rs2)>;
23162316
// Zihintpause
23172317
//===----------------------------------------------------------------------===//
23182318

2319-
// Zihintpause
2320-
let Predicates = [HasStdExtZihintpause] in
2319+
// int_riscv_pause is always available since pause is a HINT encoding that is
2320+
// guaranteed not to trap (riscv-non-isa/riscv-elf-psabi-doc#474).
23212321
def : Pat<(int_riscv_pause), (FENCE 0x1, 0x0)>;
23222322

23232323
//===----------------------------------------------------------------------===//

0 commit comments

Comments
 (0)