[ARC] Add codegen for count trailing zeros intrinsic for the ARC backend

Differential Revision: https://reviews.llvm.org/D107828
This commit is contained in:
Thomas Johnson 2021-08-07 21:05:59 +02:00 committed by Mark Schimmel
parent 76093b1739
commit b821086876
5 changed files with 70 additions and 14 deletions

View File

@ -35,8 +35,9 @@ public:
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:

View File

@ -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 {

View File

@ -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 {

View File

@ -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
}

View File

@ -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