[PATCH] D14469: [ARM] add overrides for isCheapToSpeculateCttz() and isCheapToSpeculateCtlz()

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Fri Nov 6 16:33:09 PST 2015


spatel created this revision.
spatel added reviewers: t.p.northover, rengolin, andreadb.
spatel added a subscriber: llvm-commits.
Herald added subscribers: rengolin, aemerson.

I'm a long way from home on this one... 
Believe it or not, this is one step towards solving PR24818:
https://llvm.org/bugs/show_bug.cgi?id=24818

Some background here:
http://reviews.llvm.org/rL248439

The immediate problem is that ARM is using the default TLI cost settings for count-leading/trailing-zeros. I think this should be considered a cheap operation (and therefore fair game for speculation) for any implementation with V6T2 or later. 

Another possibility is that we just invert the default settings for the base class hooks. Of the in-tree targets, I'm pretty sure that ARM64 and MIPS should also be making these ops cheap, but they're currently not.

The net result of allowing this speculation for the new ARM 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


http://reviews.llvm.org/D14469

Files:
  lib/Target/ARM/ARMISelLowering.cpp
  lib/Target/ARM/ARMISelLowering.h
  test/Transforms/SimplifyCFG/ARM/cttz-ctlz.ll
  test/Transforms/SimplifyCFG/ARM/lit.local.cfg

Index: test/Transforms/SimplifyCFG/ARM/lit.local.cfg
===================================================================
--- test/Transforms/SimplifyCFG/ARM/lit.local.cfg
+++ 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
Index: test/Transforms/SimplifyCFG/ARM/cttz-ctlz.ll
===================================================================
--- test/Transforms/SimplifyCFG/ARM/cttz-ctlz.ll
+++ 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)
+
Index: lib/Target/ARM/ARMISelLowering.h
===================================================================
--- lib/Target/ARM/ARMISelLowering.h
+++ lib/Target/ARM/ARMISelLowering.h
@@ -457,6 +457,9 @@
     bool canCombineStoreAndExtract(Type *VectorTy, Value *Idx,
                                    unsigned &Cost) const override;
 
+    bool isCheapToSpeculateCttz() const override;
+    bool isCheapToSpeculateCtlz() const override;
+
   protected:
     std::pair<const TargetRegisterClass *, uint8_t>
     findRepresentativeClass(const TargetRegisterInfo *TRI,
Index: lib/Target/ARM/ARMISelLowering.cpp
===================================================================
--- lib/Target/ARM/ARMISelLowering.cpp
+++ lib/Target/ARM/ARMISelLowering.cpp
@@ -11831,6 +11831,14 @@
   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();


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D14469.39608.patch
Type: text/x-patch
Size: 3115 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20151107/0bef26ce/attachment.bin>


More information about the llvm-commits mailing list