[llvm] b821086 - [ARC] Add codegen for count trailing zeros intrinsic for the ARC backend
Mark Schimmel via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 10 12:09:21 PDT 2021
Author: Thomas Johnson
Date: 2021-08-10T12:07:35-07:00
New Revision: b82108687689f0d511226433d16895c3da022529
URL: https://github.com/llvm/llvm-project/commit/b82108687689f0d511226433d16895c3da022529
DIFF: https://github.com/llvm/llvm-project/commit/b82108687689f0d511226433d16895c3da022529.diff
LOG: [ARC] Add codegen for count trailing zeros intrinsic for the ARC backend
Differential Revision: https://reviews.llvm.org/D107828
Added:
llvm/test/CodeGen/ARC/intrinsics.ll
Modified:
llvm/lib/Target/ARC/ARCExpandPseudos.cpp
llvm/lib/Target/ARC/ARCISelLowering.cpp
llvm/lib/Target/ARC/ARCInstrInfo.td
llvm/test/MC/Disassembler/ARC/misc.txt
Removed:
llvm/test/CodeGen/ARC/ctlz.ll
################################################################################
diff --git a/llvm/lib/Target/ARC/ARCExpandPseudos.cpp b/llvm/lib/Target/ARC/ARCExpandPseudos.cpp
index cef9882909b3f..84bb6cac28768 100644
--- a/llvm/lib/Target/ARC/ARCExpandPseudos.cpp
+++ b/llvm/lib/Target/ARC/ARCExpandPseudos.cpp
@@ -35,8 +35,9 @@ class ARCExpandPseudos : public MachineFunctionPass {
StringRef getPassName() const override { return "ARC Expand Pseudos"; }
private:
- void ExpandStore(MachineFunction &, MachineBasicBlock::iterator);
- void ExpandCTLZ(MachineFunction &, MachineBasicBlock::iterator);
+ void expandStore(MachineFunction &, MachineBasicBlock::iterator);
+ void expandCTLZ(MachineFunction &, MachineBasicBlock::iterator);
+ void expandCTTZ(MachineFunction &, MachineBasicBlock::iterator);
const ARCInstrInfo *TII;
};
@@ -58,7 +59,7 @@ static unsigned getMappedOp(unsigned PseudoOp) {
}
}
-void ARCExpandPseudos::ExpandStore(MachineFunction &MF,
+void ARCExpandPseudos::expandStore(MachineFunction &MF,
MachineBasicBlock::iterator SII) {
MachineInstr &SI = *SII;
Register AddrReg = MF.getRegInfo().createVirtualRegister(&ARC::GPR32RegClass);
@@ -75,7 +76,7 @@ void ARCExpandPseudos::ExpandStore(MachineFunction &MF,
SI.eraseFromParent();
}
-void ARCExpandPseudos::ExpandCTLZ(MachineFunction &MF,
+void ARCExpandPseudos::expandCTLZ(MachineFunction &MF,
MachineBasicBlock::iterator MII) {
// Expand:
// %R2<def> = CTLZ %R0, %STATUS<imp-def>
@@ -104,6 +105,29 @@ void ARCExpandPseudos::ExpandCTLZ(MachineFunction &MF,
MI.eraseFromParent();
}
+void ARCExpandPseudos::expandCTTZ(MachineFunction &MF,
+ MachineBasicBlock::iterator MII) {
+ // Expand:
+ // %R0<def> = CTTZ %R0<kill>, %STATUS<imp-def>
+ // To:
+ // %R0<def> = FFS_f_rr %R0<kill>, %STATUS<imp-def>
+ // %R0<def,tied1> = MOVcc_ru6 %R0<tied0>, 32, pred:1, %STATUS<imp-use>
+ MachineInstr &MI = *MII;
+ const MachineOperand &Dest = MI.getOperand(0);
+ const MachineOperand &Src = MI.getOperand(1);
+ Register R = MF.getRegInfo().createVirtualRegister(&ARC::GPR32RegClass);
+
+ BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), TII->get(ARC::FFS_f_rr), R)
+ .add(Src);
+ BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), TII->get(ARC::MOV_cc_ru6))
+ .add(Dest)
+ .addImm(32)
+ .addImm(ARCCC::EQ)
+ .addReg(R);
+
+ MI.eraseFromParent();
+}
+
bool ARCExpandPseudos::runOnMachineFunction(MachineFunction &MF) {
const ARCSubtarget *STI = &MF.getSubtarget<ARCSubtarget>();
TII = STI->getInstrInfo();
@@ -116,11 +140,15 @@ bool ARCExpandPseudos::runOnMachineFunction(MachineFunction &MF) {
case ARC::ST_FAR:
case ARC::STH_FAR:
case ARC::STB_FAR:
- ExpandStore(MF, MBBI);
+ expandStore(MF, MBBI);
Expanded = true;
break;
case ARC::CTLZ:
- ExpandCTLZ(MF, MBBI);
+ expandCTLZ(MF, MBBI);
+ Expanded = true;
+ break;
+ case ARC::CTTZ:
+ expandCTTZ(MF, MBBI);
Expanded = true;
break;
default:
diff --git a/llvm/lib/Target/ARC/ARCISelLowering.cpp b/llvm/lib/Target/ARC/ARCISelLowering.cpp
index 3db132a50b93f..271b3cf038f77 100644
--- a/llvm/lib/Target/ARC/ARCISelLowering.cpp
+++ b/llvm/lib/Target/ARC/ARCISelLowering.cpp
@@ -136,9 +136,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.
+ // TODO: Predicate these with `options.hasBitScan() ? Legal : Expand`
+ // when the HasBitScan predicate is available.
setOperationAction(ISD::CTLZ, MVT::i32, Legal);
+ setOperationAction(ISD::CTTZ, 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 22a583c2b587f..3155b22d4e0c7 100644
--- a/llvm/lib/Target/ARC/ARCInstrInfo.td
+++ b/llvm/lib/Target/ARC/ARCInstrInfo.td
@@ -133,12 +133,17 @@ 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];
+// TODO: Add `Requires<[HasBitScan]>` predicate to these when available.
+let Defs = [STATUS32] in {
+ def CTLZ : PseudoInstARC<(outs GPR32:$A),
+ (ins GPR32:$B),
+ "error.fls $A, $B",
+ [(set GPR32:$A, (ctlz i32:$B))]>;
+
+ def CTTZ : PseudoInstARC<(outs GPR32:$A),
+ (ins GPR32:$B),
+ "error.ffs $A, $B",
+ [(set GPR32:$A, (cttz i32:$B))]>;
}
//===----------------------------------------------------------------------===//
@@ -314,6 +319,7 @@ defm SEXB : ArcUnaryGEN4Inst<0b000101, "sexb">;
defm SEXH : ArcUnaryGEN4Inst<0b000110, "sexh">;
// Extension unary instruction definitions.
+defm FFS : ArcUnaryEXT5Inst<0b010010, "ffs">;
defm FLS : ArcUnaryEXT5Inst<0b010011, "fls">;
let Predicates=[HasNorm] in {
diff --git a/llvm/test/CodeGen/ARC/ctlz.ll b/llvm/test/CodeGen/ARC/intrinsics.ll
similarity index 59%
rename from llvm/test/CodeGen/ARC/ctlz.ll
rename to llvm/test/CodeGen/ARC/intrinsics.ll
index 1702a5c5b040a..5eebbb339dcc9 100644
--- a/llvm/test/CodeGen/ARC/ctlz.ll
+++ b/llvm/test/CodeGen/ARC/intrinsics.ll
@@ -3,6 +3,7 @@
target triple = "arc"
declare i32 @llvm.ctlz.i32(i32, i1)
+declare i32 @llvm.cttz.i32(i32, i1)
; CHECK-LABEL: clz32:
; CHECK: fls.f %r0, %r0
@@ -12,3 +13,11 @@ define i32 @clz32(i32 %x) {
%a = call i32 @llvm.ctlz.i32(i32 %x, i1 false)
ret i32 %a
}
+
+; CHECK-LABEL: ctz32:
+; CHECK: ffs.f %r0, %r0
+; CHECK-NEXT: mov.eq %r0, 32
+define i32 @ctz32(i32 %x) {
+ %a = call i32 @llvm.cttz.i32(i32 %x, i1 false)
+ ret i32 %a
+}
diff --git a/llvm/test/MC/Disassembler/ARC/misc.txt b/llvm/test/MC/Disassembler/ARC/misc.txt
index 45ba9b00382d6..8282cb57bc768 100644
--- a/llvm/test/MC/Disassembler/ARC/misc.txt
+++ b/llvm/test/MC/Disassembler/ARC/misc.txt
@@ -130,6 +130,18 @@
# CHECK: fls.f %r0, %r0
0x2f 0x28 0x13 0x80
+# CHECK: ffs %r0, %r0
+0x2f 0x28 0x12 0x00
+
+# CHECK: ffs.f %r0, %r0
+0x2f 0x28 0x12 0x80
+
+# CHECK: ffs %r15, %r15
+0x2f 0x2f 0xd2 0x13
+
+# CHECK: ffs.f %r15, %r15
+0x2f 0x2f 0xd2 0x93
+
# CHECK: norm %r22, %blink
0x2f 0x2e 0xc1 0x27
More information about the llvm-commits
mailing list