[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