[llvm] f8a4495 - [ARC] Add codegen for llvm.ctlz intrinsic for the ARC backend
Mark Schimmel via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 6 12:19:47 PDT 2021
Author: Thomas Johnson
Date: 2021-08-06T12:18:06-07:00
New Revision: f8a449514931bf2b3a0b36328e821365ed8bf5c6
URL: https://github.com/llvm/llvm-project/commit/f8a449514931bf2b3a0b36328e821365ed8bf5c6
DIFF: https://github.com/llvm/llvm-project/commit/f8a449514931bf2b3a0b36328e821365ed8bf5c6.diff
LOG: [ARC] Add codegen for llvm.ctlz intrinsic for the ARC backend
Differential Revision: https://reviews.llvm.org/D107611
Added:
llvm/test/CodeGen/ARC/ctlz.ll
Modified:
clang/lib/Basic/Targets/ARC.h
llvm/lib/Target/ARC/ARCExpandPseudos.cpp
llvm/lib/Target/ARC/ARCISelLowering.cpp
llvm/lib/Target/ARC/ARCInstrInfo.td
Removed:
################################################################################
diff --git a/clang/lib/Basic/Targets/ARC.h b/clang/lib/Basic/Targets/ARC.h
index b314c42be1e94..3c0c5f6df2f4d 100644
--- a/clang/lib/Basic/Targets/ARC.h
+++ b/clang/lib/Basic/Targets/ARC.h
@@ -67,6 +67,8 @@ class LLVM_LIBRARY_VISIBILITY ARCTargetInfo : public TargetInfo {
}
bool hasExtIntType() const override { return true; }
+
+ bool isCLZForZeroUndef() const override { return false; }
};
} // namespace targets
diff --git a/llvm/lib/Target/ARC/ARCExpandPseudos.cpp b/llvm/lib/Target/ARC/ARCExpandPseudos.cpp
index a1646d17605fe..cef9882909b3f 100644
--- a/llvm/lib/Target/ARC/ARCExpandPseudos.cpp
+++ b/llvm/lib/Target/ARC/ARCExpandPseudos.cpp
@@ -13,6 +13,7 @@
#include "ARCInstrInfo.h"
#include "ARCRegisterInfo.h"
#include "ARCSubtarget.h"
+#include "MCTargetDesc/ARCInfo.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
@@ -35,6 +36,7 @@ class ARCExpandPseudos : public MachineFunctionPass {
private:
void ExpandStore(MachineFunction &, MachineBasicBlock::iterator);
+ void ExpandCTLZ(MachineFunction &, MachineBasicBlock::iterator);
const ARCInstrInfo *TII;
};
@@ -59,8 +61,8 @@ static unsigned getMappedOp(unsigned PseudoOp) {
void ARCExpandPseudos::ExpandStore(MachineFunction &MF,
MachineBasicBlock::iterator SII) {
MachineInstr &SI = *SII;
- unsigned AddrReg = MF.getRegInfo().createVirtualRegister(&ARC::GPR32RegClass);
- unsigned AddOpc =
+ Register AddrReg = MF.getRegInfo().createVirtualRegister(&ARC::GPR32RegClass);
+ Register AddOpc =
isUInt<6>(SI.getOperand(2).getImm()) ? ARC::ADD_rru6 : ARC::ADD_rrlimm;
BuildMI(*SI.getParent(), SI, SI.getDebugLoc(), TII->get(AddOpc), AddrReg)
.addReg(SI.getOperand(1).getReg())
@@ -73,10 +75,39 @@ void ARCExpandPseudos::ExpandStore(MachineFunction &MF,
SI.eraseFromParent();
}
+void ARCExpandPseudos::ExpandCTLZ(MachineFunction &MF,
+ MachineBasicBlock::iterator MII) {
+ // Expand:
+ // %R2<def> = CTLZ %R0, %STATUS<imp-def>
+ // To:
+ // %R2<def> = FLS_f_rr %R0, %STATUS<imp-def>
+ // %R2<def,tied1> = MOV_cc_ru6 %R2<tied0>, 32, pred:1, %STATUS<imp-use>
+ // %R2<def,tied1> = RSUB_cc_rru6 %R2<tied0>, 31, pred:2, %STATUS<imp-use>
+ MachineInstr &MI = *MII;
+ const MachineOperand &Dest = MI.getOperand(0);
+ const MachineOperand &Src = MI.getOperand(1);
+ Register Ra = MF.getRegInfo().createVirtualRegister(&ARC::GPR32RegClass);
+ Register Rb = MF.getRegInfo().createVirtualRegister(&ARC::GPR32RegClass);
+
+ BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), TII->get(ARC::FLS_f_rr), Ra)
+ .add(Src);
+ BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), TII->get(ARC::MOV_cc_ru6), Rb)
+ .addImm(32)
+ .addImm(ARCCC::EQ)
+ .addReg(Ra);
+ BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), TII->get(ARC::RSUB_cc_rru6))
+ .add(Dest)
+ .addImm(31)
+ .addImm(ARCCC::NE)
+ .addReg(Rb);
+
+ MI.eraseFromParent();
+}
+
bool ARCExpandPseudos::runOnMachineFunction(MachineFunction &MF) {
const ARCSubtarget *STI = &MF.getSubtarget<ARCSubtarget>();
TII = STI->getInstrInfo();
- bool ExpandedStore = false;
+ bool Expanded = false;
for (auto &MBB : MF) {
MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
while (MBBI != E) {
@@ -86,7 +117,11 @@ bool ARCExpandPseudos::runOnMachineFunction(MachineFunction &MF) {
case ARC::STH_FAR:
case ARC::STB_FAR:
ExpandStore(MF, MBBI);
- ExpandedStore = true;
+ Expanded = true;
+ break;
+ case ARC::CTLZ:
+ ExpandCTLZ(MF, MBBI);
+ Expanded = true;
break;
default:
break;
@@ -94,7 +129,7 @@ bool ARCExpandPseudos::runOnMachineFunction(MachineFunction &MF) {
MBBI = NMBBI;
}
}
- return ExpandedStore;
+ return Expanded;
}
FunctionPass *llvm::createARCExpandPseudosPass() {
diff --git a/llvm/lib/Target/ARC/ARCISelLowering.cpp b/llvm/lib/Target/ARC/ARCISelLowering.cpp
index ca33f52974711..3db132a50b93f 100644
--- a/llvm/lib/Target/ARC/ARCISelLowering.cpp
+++ b/llvm/lib/Target/ARC/ARCISelLowering.cpp
@@ -135,6 +135,10 @@ ARCTargetLowering::ARCTargetLowering(const TargetMachine &TM,
// Sign extend inreg
setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Custom);
+
+ // TODO: Predicate with `options.hasBitScan() ? Legal : Expand` when
+ // the HasBitScan predicate is available.
+ setOperationAction(ISD::CTLZ, MVT::i32, Legal);
}
const char *ARCTargetLowering::getTargetNodeName(unsigned Opcode) const {
diff --git a/llvm/lib/Target/ARC/ARCInstrInfo.td b/llvm/lib/Target/ARC/ARCInstrInfo.td
index 16c3e50635bf8..22a583c2b587f 100644
--- a/llvm/lib/Target/ARC/ARCInstrInfo.td
+++ b/llvm/lib/Target/ARC/ARCInstrInfo.td
@@ -133,6 +133,14 @@ def STB_FAR : PseudoInstARC<(outs), (ins GPR32:$dst, MEMrlimm:$addr),
"STB_FAR $dst, $addr",
[(truncstorei8 GPR32:$dst, AddrModeFar:$addr)]>;
+// TODO: Add `Requires<[HasBitScan]>` predicate when available.
+def CTLZ : PseudoInstARC<(outs GPR32:$A),
+ (ins GPR32:$B),
+ "error.fls $A, $B",
+ [(set GPR32:$A, (ctlz i32:$B))]> {
+ let Defs = [STATUS32];
+}
+
//===----------------------------------------------------------------------===//
// Instruction Generation multiclasses.
// Generate many variants of a single instruction with a single defining
diff --git a/llvm/test/CodeGen/ARC/ctlz.ll b/llvm/test/CodeGen/ARC/ctlz.ll
new file mode 100644
index 0000000000000..1702a5c5b040a
--- /dev/null
+++ b/llvm/test/CodeGen/ARC/ctlz.ll
@@ -0,0 +1,14 @@
+; RUN: llc -march=arc < %s | FileCheck %s
+
+target triple = "arc"
+
+declare i32 @llvm.ctlz.i32(i32, i1)
+
+; CHECK-LABEL: clz32:
+; CHECK: fls.f %r0, %r0
+; CHECK-NEXT: mov.eq %r0, 32
+; CHECK-NEXT: rsub.ne %r0, %r0, 31
+define i32 @clz32(i32 %x) {
+ %a = call i32 @llvm.ctlz.i32(i32 %x, i1 false)
+ ret i32 %a
+}
More information about the llvm-commits
mailing list