Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit da103fa

Browse files
committed
[ARM] add overrides for isCheapToSpeculateCttz() and isCheapToSpeculateCtlz()
ARM V6T2 has instructions for efficient count-leading/trailing-zeros, so this should be considered a cheap operation (and therefore fair game for speculation) for any ARM V6T2 implementation. The net result of allowing this speculation for the regression tests in this patch is that we get this code: ctlz: clz r0, r0 bx lr cttz: rbit r0, r0 clz r0, r0 bx lr Instead of: ctlz: cmp r0, #0 moveq r0, #32 clzne r0, r0 bx lr cttz: cmp r0, #0 moveq r0, #32 rbitne r0, r0 clzne r0, r0 bx lr This will help solve a general speculation/despeculation problem noted in PR24818: https://llvm.org/bugs/show_bug.cgi?id=24818 Differential Revision: http://reviews.llvm.org/D14469 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@252639 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent a987cc6 commit da103fa

File tree

4 files changed

+59
-0
lines changed

4 files changed

+59
-0
lines changed

lib/Target/ARM/ARMISelLowering.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -11841,6 +11841,14 @@ bool ARMTargetLowering::canCombineStoreAndExtract(Type *VectorTy, Value *Idx,
1184111841
return false;
1184211842
}
1184311843

11844+
bool ARMTargetLowering::isCheapToSpeculateCttz() const {
11845+
return Subtarget->hasV6T2Ops();
11846+
}
11847+
11848+
bool ARMTargetLowering::isCheapToSpeculateCtlz() const {
11849+
return Subtarget->hasV6T2Ops();
11850+
}
11851+
1184411852
Value *ARMTargetLowering::emitLoadLinked(IRBuilder<> &Builder, Value *Addr,
1184511853
AtomicOrdering Ord) const {
1184611854
Module *M = Builder.GetInsertBlock()->getParent()->getParent();

lib/Target/ARM/ARMISelLowering.h

+3
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,9 @@ namespace llvm {
467467
bool canCombineStoreAndExtract(Type *VectorTy, Value *Idx,
468468
unsigned &Cost) const override;
469469

470+
bool isCheapToSpeculateCttz() const override;
471+
bool isCheapToSpeculateCtlz() const override;
472+
470473
protected:
471474
std::pair<const TargetRegisterClass *, uint8_t>
472475
findRepresentativeClass(const TargetRegisterInfo *TRI,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
; RUN: opt -S -simplifycfg -mtriple=arm -mattr=+v6t2 < %s | FileCheck %s
2+
3+
define i32 @ctlz(i32 %A) {
4+
; CHECK-LABEL: @ctlz(
5+
; CHECK: [[ICMP:%[A-Za-z0-9]+]] = icmp eq i32 %A, 0
6+
; CHECK-NEXT: [[CTZ:%[A-Za-z0-9]+]] = tail call i32 @llvm.ctlz.i32(i32 %A, i1 true)
7+
; CHECK-NEXT: [[SEL:%[A-Za-z0-9.]+]] = select i1 [[ICMP]], i32 32, i32 [[CTZ]]
8+
; CHECK-NEXT: ret i32 [[SEL]]
9+
entry:
10+
%tobool = icmp eq i32 %A, 0
11+
br i1 %tobool, label %cond.end, label %cond.true
12+
13+
cond.true:
14+
%0 = tail call i32 @llvm.ctlz.i32(i32 %A, i1 true)
15+
br label %cond.end
16+
17+
cond.end:
18+
%cond = phi i32 [ %0, %cond.true ], [ 32, %entry ]
19+
ret i32 %cond
20+
}
21+
22+
define i32 @cttz(i32 %A) {
23+
; CHECK-LABEL: @cttz(
24+
; CHECK: [[ICMP:%[A-Za-z0-9]+]] = icmp eq i32 %A, 0
25+
; CHECK-NEXT: [[CTZ:%[A-Za-z0-9]+]] = tail call i32 @llvm.cttz.i32(i32 %A, i1 true)
26+
; CHECK-NEXT: [[SEL:%[A-Za-z0-9.]+]] = select i1 [[ICMP]], i32 32, i32 [[CTZ]]
27+
; CHECK-NEXT: ret i32 [[SEL]]
28+
entry:
29+
%tobool = icmp eq i32 %A, 0
30+
br i1 %tobool, label %cond.end, label %cond.true
31+
32+
cond.true:
33+
%0 = tail call i32 @llvm.cttz.i32(i32 %A, i1 true)
34+
br label %cond.end
35+
36+
cond.end:
37+
%cond = phi i32 [ %0, %cond.true ], [ 32, %entry ]
38+
ret i32 %cond
39+
}
40+
41+
declare i32 @llvm.ctlz.i32(i32, i1)
42+
declare i32 @llvm.cttz.i32(i32, i1)
43+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
config.suffixes = ['.ll']
2+
3+
targets = set(config.root.targets_to_build.split())
4+
if not 'ARM' in targets:
5+
config.unsupported = True

0 commit comments

Comments
 (0)