Skip to content

Commit d3acb44

Browse files
committed
[Xtensa] Implement CTLZ/CTTZ with NSAU
Close #77
1 parent 4cd5e09 commit d3acb44

File tree

5 files changed

+104
-5
lines changed

5 files changed

+104
-5
lines changed

llvm/lib/Target/Xtensa/XtensaISelLowering.cpp

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -192,10 +192,12 @@ XtensaTargetLowering::XtensaTargetLowering(const TargetMachine &TM,
192192
setOperationAction(ISD::ROTL, MVT::i32, Expand);
193193
setOperationAction(ISD::ROTR, MVT::i32, Expand);
194194
setOperationAction(ISD::CTPOP, MVT::i32, Custom);
195-
setOperationAction(ISD::CTTZ, MVT::i32, Expand);
196-
setOperationAction(ISD::CTLZ, MVT::i32, Expand);
197-
setOperationAction(ISD::CTTZ_ZERO_UNDEF, MVT::i32, Expand);
198-
setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i32, Expand);
195+
setOperationAction({ISD::CTTZ, ISD::CTTZ_ZERO_UNDEF}, MVT::i32, Expand);
196+
if (Subtarget.hasNSA())
197+
setOperationAction(ISD::CTLZ, MVT::i32, Legal);
198+
else
199+
setOperationAction({ISD::CTLZ, ISD::CTLZ_ZERO_UNDEF}, MVT::i32, Expand);
200+
199201

200202
setOperationAction({ISD::SMIN, ISD::SMAX, ISD::UMIN, ISD::UMAX},
201203
MVT::i32, Subtarget.hasMINMAX() ? Legal : Expand);
@@ -407,6 +409,18 @@ bool XtensaTargetLowering::isFMAFasterThanFMulAndFAdd(const MachineFunction &MF,
407409
return false;
408410
}
409411

412+
bool XtensaTargetLowering::isCheapToSpeculateCtlz(Type *) const {
413+
return Subtarget.hasNSA();
414+
}
415+
416+
bool XtensaTargetLowering::isCheapToSpeculateCttz(Type *) const {
417+
return Subtarget.hasNSA();
418+
}
419+
420+
bool XtensaTargetLowering::isCtlzFast() const {
421+
return Subtarget.hasNSA();
422+
}
423+
410424
/// If a physical register, this returns the register that receives the
411425
/// exception address on entry to an EH pad.
412426
Register XtensaTargetLowering::getExceptionPointerRegister(

llvm/lib/Target/Xtensa/XtensaISelLowering.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,11 @@ class XtensaTargetLowering : public TargetLowering {
120120
EVT VT) const override;
121121

122122
bool isFNegFree(EVT VT) const override;
123+
bool isCheapToSpeculateCtlz(Type *Ty) const override;
124+
125+
bool isCheapToSpeculateCttz(Type *Ty) const override;
126+
127+
bool isCtlzFast() const override;
123128

124129
/// If a physical register, this returns the register that receives the
125130
/// exception address on entry to an EH pad.

llvm/lib/Target/Xtensa/XtensaInstrInfo.td

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1309,7 +1309,8 @@ def NSA : RRR_Inst<0x00, 0x00, 0x04, (outs AR:$t), (ins AR:$s),
13091309
}
13101310

13111311
def NSAU : RRR_Inst<0x00, 0x00, 0x04, (outs AR:$t), (ins AR:$s),
1312-
"nsau\t$t, $s", []>, Requires<[HasNSA]> {
1312+
"nsau\t$t, $s",
1313+
[(set AR:$t, (ctlz AR:$s))]>, Requires<[HasNSA]> {
13131314
let r = 0xF;
13141315
}
13151316

llvm/test/CodeGen/Xtensa/ctlz-cttz.ll

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc -mtriple=xtensa -mcpu=esp32 -verify-machineinstrs < %s \
3+
; RUN: | FileCheck -check-prefix=XTENSA %s
4+
5+
declare i32 @llvm.ctlz.i32(i32, i1)
6+
7+
define i32 @test1_ctlz(i32 %v) {
8+
; XTENSA-LABEL: test1_ctlz:
9+
; XTENSA: # %bb.0:
10+
; XTENSA-NEXT: entry a1, 32
11+
; XTENSA-NEXT: .cfi_def_cfa_offset 32
12+
; XTENSA-NEXT: nsau a2, a2
13+
; XTENSA-NEXT: retw.n
14+
%1 = tail call i32 @llvm.ctlz.i32(i32 %v, i1 false)
15+
ret i32 %1
16+
}
17+
18+
define i32 @test2_ctlz(i32 %v) {
19+
; XTENSA-LABEL: test2_ctlz:
20+
; XTENSA: # %bb.0:
21+
; XTENSA-NEXT: entry a1, 32
22+
; XTENSA-NEXT: .cfi_def_cfa_offset 32
23+
; XTENSA-NEXT: nsau a2, a2
24+
; XTENSA-NEXT: retw.n
25+
%cnt = tail call i32 @llvm.ctlz.i32(i32 %v, i1 true)
26+
%tobool = icmp eq i32 %v, 0
27+
%cond = select i1 %tobool, i32 32, i32 %cnt
28+
ret i32 %cond
29+
}
30+
31+
declare i32 @llvm.cttz.i32(i32, i1)
32+
33+
define i32 @test1_cttz(i32 %v) {
34+
; XTENSA-LABEL: test1_cttz:
35+
; XTENSA: # %bb.0:
36+
; XTENSA-NEXT: entry a1, 32
37+
; XTENSA-NEXT: .cfi_def_cfa_offset 32
38+
; XTENSA-NEXT: movi.n a8, -1
39+
; XTENSA-NEXT: xor a8, a2, a8
40+
; XTENSA-NEXT: addi.n a9, a2, -1
41+
; XTENSA-NEXT: and a8, a8, a9
42+
; XTENSA-NEXT: nsau a8, a8
43+
; XTENSA-NEXT: movi.n a9, 32
44+
; XTENSA-NEXT: sub a2, a9, a8
45+
; XTENSA-NEXT: retw.n
46+
%1 = tail call i32 @llvm.cttz.i32(i32 %v, i1 false)
47+
ret i32 %1
48+
}
49+
50+
define i32 @test2_cttz(i32 %v) {
51+
; XTENSA-LABEL: test2_cttz:
52+
; XTENSA: # %bb.0:
53+
; XTENSA-NEXT: entry a1, 32
54+
; XTENSA-NEXT: .cfi_def_cfa_offset 32
55+
; XTENSA-NEXT: movi.n a8, -1
56+
; XTENSA-NEXT: xor a8, a2, a8
57+
; XTENSA-NEXT: addi.n a9, a2, -1
58+
; XTENSA-NEXT: and a8, a8, a9
59+
; XTENSA-NEXT: nsau a8, a8
60+
; XTENSA-NEXT: movi.n a9, 32
61+
; XTENSA-NEXT: sub a2, a9, a8
62+
; XTENSA-NEXT: retw.n
63+
%cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true)
64+
%tobool = icmp eq i32 %v, 0
65+
%cond = select i1 %tobool, i32 32, i32 %cnt
66+
ret i32 %cond
67+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# RUN: llvm-mc %s -triple=xtensa -mattr=+nsa -show-encoding \
2+
# RUN: | FileCheck -check-prefixes=CHECK,CHECK-INST %s
3+
4+
# Instruction format RRR
5+
# CHECK-INST: nsa a3, a2
6+
# CHECK: encoding: [0x30,0xe2,0x40]
7+
nsa a3, a2
8+
9+
# Instruction format RRR
10+
# CHECK-INST: nsau a3, a2
11+
# CHECK: encoding: [0x30,0xf2,0x40]
12+
nsau a3, a2

0 commit comments

Comments
 (0)