[llvm] 270c179 - [AArch64][GISel] Lower llvm.prefetch
Archibald Elliott via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 19 01:12:13 PDT 2022
Author: Archibald Elliott
Date: 2022-08-19T09:11:18+01:00
New Revision: 270c179afd0ecf4de5f9b00af027e2033bbcf998
URL: https://github.com/llvm/llvm-project/commit/270c179afd0ecf4de5f9b00af027e2033bbcf998
DIFF: https://github.com/llvm/llvm-project/commit/270c179afd0ecf4de5f9b00af027e2033bbcf998.diff
LOG: [AArch64][GISel] Lower llvm.prefetch
This change adds support for lowering llvm.prefetch directly using
GlobalISel. Currently, llvm.prefetch falls back to SelectionDAG.
This Change:
- Adds an AArch64-specific G_PREFETCH generic instruction, to be used
where AArch64ISD::PREFETCH is used in SelectionDAG.
- Adds the GINodeEquiv so patterns are translated over to GlobalISel
automatically.
- Corrects the AArch64Prefetch patterns to use a target immediate, which
is needed to get the patterns to translate across correctly.
- Translates the SelectionDAG legalisation of the prefetch intrinsic
into the corresponding GlobalISel legalisation.
Differential Revision: https://reviews.llvm.org/D132043
Added:
Modified:
llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
llvm/lib/Target/AArch64/AArch64InstrFormats.td
llvm/lib/Target/AArch64/AArch64InstrGISel.td
llvm/lib/Target/AArch64/AArch64InstrInfo.td
llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
llvm/test/CodeGen/AArch64/arm64-prefetch.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 16c3d96807674..fb945a3c6abe1 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -3695,7 +3695,8 @@ static SDValue LowerPREFETCH(SDValue Op, SelectionDAG &DAG) {
(Locality << 1) | // Cache level bits
(unsigned)IsStream; // Stream bit
return DAG.getNode(AArch64ISD::PREFETCH, DL, MVT::Other, Op.getOperand(0),
- DAG.getConstant(PrfOp, DL, MVT::i32), Op.getOperand(1));
+ DAG.getTargetConstant(PrfOp, DL, MVT::i32),
+ Op.getOperand(1));
}
SDValue AArch64TargetLowering::LowerFP_EXTEND(SDValue Op,
diff --git a/llvm/lib/Target/AArch64/AArch64InstrFormats.td b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
index 9796471021c8b..f908460df1fdf 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
@@ -3890,7 +3890,7 @@ class BasePrefetchRO<bits<2> sz, bit V, bits<2> opc, dag outs, dag ins,
multiclass PrefetchRO<bits<2> sz, bit V, bits<2> opc, string asm> {
def roW : BasePrefetchRO<sz, V, opc, (outs),
(ins prfop:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
- asm, [(AArch64Prefetch imm:$Rt,
+ asm, [(AArch64Prefetch timm:$Rt,
(ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
ro_Wextend64:$extend))]> {
let Inst{13} = 0b0;
@@ -3898,7 +3898,7 @@ multiclass PrefetchRO<bits<2> sz, bit V, bits<2> opc, string asm> {
def roX : BasePrefetchRO<sz, V, opc, (outs),
(ins prfop:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
- asm, [(AArch64Prefetch imm:$Rt,
+ asm, [(AArch64Prefetch timm:$Rt,
(ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
ro_Xextend64:$extend))]> {
let Inst{13} = 0b1;
diff --git a/llvm/lib/Target/AArch64/AArch64InstrGISel.td b/llvm/lib/Target/AArch64/AArch64InstrGISel.td
index 58b6dcadfc386..d4cf76a8e3f4a 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrGISel.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrGISel.td
@@ -209,6 +209,12 @@ def G_FCMLTZ : AArch64GenericInstruction {
let hasSideEffects = 0;
}
+def G_PREFETCH : AArch64GenericInstruction {
+ let OutOperandList = (outs);
+ let InOperandList = (ins type0:$imm, ptype0:$src1);
+ let hasSideEffects = 1;
+}
+
def : GINodeEquiv<G_REV16, AArch64rev16>;
def : GINodeEquiv<G_REV32, AArch64rev32>;
def : GINodeEquiv<G_REV64, AArch64rev64>;
@@ -241,6 +247,8 @@ def : GINodeEquiv<G_FCMLTZ, AArch64fcmltz>;
def : GINodeEquiv<G_EXTRACT_VECTOR_ELT, vector_extract>;
+def : GINodeEquiv<G_PREFETCH, AArch64Prefetch>;
+
// These are patterns that we only use for GlobalISel via the importer.
def : Pat<(f32 (fadd (vector_extract (v2f32 FPR64:$Rn), (i64 0)),
(vector_extract (v2f32 FPR64:$Rn), (i64 1)))),
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index 7217d9d020831..4ea6e39f40b31 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -2938,7 +2938,7 @@ def : Pat<(i64 (zextloadi32 (am_indexed32 GPR64sp:$Rn, uimm12s4:$offset))),
// Pre-fetch.
def PRFMui : PrefetchUI<0b11, 0, 0b10, "prfm",
- [(AArch64Prefetch imm:$Rt,
+ [(AArch64Prefetch timm:$Rt,
(am_indexed64 GPR64sp:$Rn,
uimm12s8:$offset))]>;
@@ -3183,7 +3183,7 @@ def : InstAlias<"ldrsw $Rt, [$Rn, $offset]",
// Pre-fetch.
defm PRFUM : PrefetchUnscaled<0b11, 0, 0b10, "prfum",
- [(AArch64Prefetch imm:$Rt,
+ [(AArch64Prefetch timm:$Rt,
(am_unscaled64 GPR64sp:$Rn, simm9:$offset))]>;
//---
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
index d158519b10523..52fcd2231bd07 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
@@ -1025,6 +1025,30 @@ bool AArch64LegalizerInfo::legalizeIntrinsic(LegalizerHelper &Helper,
Value.setReg(ZExtValueReg);
return true;
}
+ case Intrinsic::prefetch: {
+ MachineIRBuilder MIB(MI);
+ auto &AddrVal = MI.getOperand(1);
+
+ int64_t IsWrite = MI.getOperand(2).getImm();
+ int64_t Locality = MI.getOperand(3).getImm();
+ int64_t IsData = MI.getOperand(4).getImm();
+
+ bool IsStream = Locality == 0;
+ if (Locality != 0) {
+ assert(Locality <= 3 && "Prefetch locality out-of-range");
+ // The locality degree is the opposite of the cache speed.
+ // Put the number the other way around.
+ // The encoding starts at 0 for level 1
+ Locality = 3 - Locality;
+ }
+
+ unsigned PrfOp =
+ (IsWrite << 4) | (!IsData << 3) | (Locality << 1) | IsStream;
+
+ MIB.buildInstr(AArch64::G_PREFETCH).addImm(PrfOp).add(AddrVal);
+ MI.eraseFromParent();
+ return true;
+ }
}
return true;
diff --git a/llvm/test/CodeGen/AArch64/arm64-prefetch.ll b/llvm/test/CodeGen/AArch64/arm64-prefetch.ll
index 733ba94b110ff..3d526640613e3 100644
--- a/llvm/test/CodeGen/AArch64/arm64-prefetch.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-prefetch.ll
@@ -1,4 +1,5 @@
; RUN: llc < %s -mtriple=arm64-eabi | FileCheck %s
+; RUN: llc -O0 --global-isel-abort=1 < %s -mtriple=arm64-eabi | FileCheck %s
@a = common global i32* null, align 8
More information about the llvm-commits
mailing list