forked from OSchip/llvm-project
[ARC] Add codegen for count trailing zeros intrinsic for the ARC backend
Differential Revision: https://reviews.llvm.org/D107828
This commit is contained in:
parent
76093b1739
commit
b821086876
|
@ -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:
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue