From da103fa05e4483d465bb0c6991fae5ce35f617d9 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Tue, 10 Nov 2015 19:24:31 +0000 Subject: [PATCH] [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 --- lib/Target/ARM/ARMISelLowering.cpp | 8 +++++ lib/Target/ARM/ARMISelLowering.h | 3 ++ test/Transforms/SimplifyCFG/ARM/cttz-ctlz.ll | 43 +++++++++++++++++++++++++++ test/Transforms/SimplifyCFG/ARM/lit.local.cfg | 5 ++++ 4 files changed, 59 insertions(+) create mode 100644 test/Transforms/SimplifyCFG/ARM/cttz-ctlz.ll create mode 100644 test/Transforms/SimplifyCFG/ARM/lit.local.cfg diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index b83d3f78a34..01c8d7534ee 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -11841,6 +11841,14 @@ bool ARMTargetLowering::canCombineStoreAndExtract(Type *VectorTy, Value *Idx, return false; } +bool ARMTargetLowering::isCheapToSpeculateCttz() const { + return Subtarget->hasV6T2Ops(); +} + +bool ARMTargetLowering::isCheapToSpeculateCtlz() const { + return Subtarget->hasV6T2Ops(); +} + Value *ARMTargetLowering::emitLoadLinked(IRBuilder<> &Builder, Value *Addr, AtomicOrdering Ord) const { Module *M = Builder.GetInsertBlock()->getParent()->getParent(); diff --git a/lib/Target/ARM/ARMISelLowering.h b/lib/Target/ARM/ARMISelLowering.h index 534f92b941c..b0881c2df88 100644 --- a/lib/Target/ARM/ARMISelLowering.h +++ b/lib/Target/ARM/ARMISelLowering.h @@ -467,6 +467,9 @@ namespace llvm { bool canCombineStoreAndExtract(Type *VectorTy, Value *Idx, unsigned &Cost) const override; + bool isCheapToSpeculateCttz() const override; + bool isCheapToSpeculateCtlz() const override; + protected: std::pair findRepresentativeClass(const TargetRegisterInfo *TRI, diff --git a/test/Transforms/SimplifyCFG/ARM/cttz-ctlz.ll b/test/Transforms/SimplifyCFG/ARM/cttz-ctlz.ll new file mode 100644 index 00000000000..ffcf2175091 --- /dev/null +++ b/test/Transforms/SimplifyCFG/ARM/cttz-ctlz.ll @@ -0,0 +1,43 @@ +; RUN: opt -S -simplifycfg -mtriple=arm -mattr=+v6t2 < %s | FileCheck %s + +define i32 @ctlz(i32 %A) { +; CHECK-LABEL: @ctlz( +; CHECK: [[ICMP:%[A-Za-z0-9]+]] = icmp eq i32 %A, 0 +; CHECK-NEXT: [[CTZ:%[A-Za-z0-9]+]] = tail call i32 @llvm.ctlz.i32(i32 %A, i1 true) +; CHECK-NEXT: [[SEL:%[A-Za-z0-9.]+]] = select i1 [[ICMP]], i32 32, i32 [[CTZ]] +; CHECK-NEXT: ret i32 [[SEL]] +entry: + %tobool = icmp eq i32 %A, 0 + br i1 %tobool, label %cond.end, label %cond.true + +cond.true: + %0 = tail call i32 @llvm.ctlz.i32(i32 %A, i1 true) + br label %cond.end + +cond.end: + %cond = phi i32 [ %0, %cond.true ], [ 32, %entry ] + ret i32 %cond +} + +define i32 @cttz(i32 %A) { +; CHECK-LABEL: @cttz( +; CHECK: [[ICMP:%[A-Za-z0-9]+]] = icmp eq i32 %A, 0 +; CHECK-NEXT: [[CTZ:%[A-Za-z0-9]+]] = tail call i32 @llvm.cttz.i32(i32 %A, i1 true) +; CHECK-NEXT: [[SEL:%[A-Za-z0-9.]+]] = select i1 [[ICMP]], i32 32, i32 [[CTZ]] +; CHECK-NEXT: ret i32 [[SEL]] +entry: + %tobool = icmp eq i32 %A, 0 + br i1 %tobool, label %cond.end, label %cond.true + +cond.true: + %0 = tail call i32 @llvm.cttz.i32(i32 %A, i1 true) + br label %cond.end + +cond.end: + %cond = phi i32 [ %0, %cond.true ], [ 32, %entry ] + ret i32 %cond +} + +declare i32 @llvm.ctlz.i32(i32, i1) +declare i32 @llvm.cttz.i32(i32, i1) + diff --git a/test/Transforms/SimplifyCFG/ARM/lit.local.cfg b/test/Transforms/SimplifyCFG/ARM/lit.local.cfg new file mode 100644 index 00000000000..5a3b8565213 --- /dev/null +++ b/test/Transforms/SimplifyCFG/ARM/lit.local.cfg @@ -0,0 +1,5 @@ +config.suffixes = ['.ll'] + +targets = set(config.root.targets_to_build.split()) +if not 'ARM' in targets: + config.unsupported = True -- 2.11.0