OSDN Git Service

[Hexagon] Counting leading/trailing bits is cheap
authorKrzysztof Parzyszek <kparzysz@codeaurora.org>
Mon, 12 Mar 2018 18:18:23 +0000 (18:18 +0000)
committerKrzysztof Parzyszek <kparzysz@codeaurora.org>
Mon, 12 Mar 2018 18:18:23 +0000 (18:18 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@327308 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/Hexagon/HexagonISelLowering.h
test/CodeGen/Hexagon/countbits-basic.ll [new file with mode: 0644]

index 607d852..de1f6ae 100644 (file)
@@ -121,6 +121,10 @@ namespace HexagonISD {
     bool isTruncateFree(Type *Ty1, Type *Ty2) const override;
     bool isTruncateFree(EVT VT1, EVT VT2) const override;
 
+    bool isCheapToSpeculateCttz() const override { return true; }
+    bool isCheapToSpeculateCtlz() const override { return true; }
+    bool isCtlzFast() const override { return true; }
+
     bool allowTruncateForTailCall(Type *Ty1, Type *Ty2) const override;
 
     /// Return true if an FMA operation is faster than a pair of mul and add
diff --git a/test/CodeGen/Hexagon/countbits-basic.ll b/test/CodeGen/Hexagon/countbits-basic.ll
new file mode 100644 (file)
index 0000000..f2c21f1
--- /dev/null
@@ -0,0 +1,75 @@
+; RUN: llc -march=hexagon < %s | FileCheck %s
+
+; CHECK: count_leading_0:
+; CHECK: cl0(r0)
+define i32 @count_leading_0(i32 %p) #0 {
+  %1 = call i32 @llvm.ctlz.i32(i32 %p, i1 false)
+  ret i32 %1
+}
+
+; CHECK: count_leading_0p:
+; CHECK: cl0(r1:0)
+define i32 @count_leading_0p(i64 %p) #0 {
+  %1 = call i64 @llvm.ctlz.i64(i64 %p, i1 false)
+  %2 = trunc i64 %1 to i32
+  ret i32 %2
+}
+
+; CHECK: count_leading_1:
+; CHECK: cl1(r0)
+define i32 @count_leading_1(i32 %p) #0 {
+  %1 = xor i32 %p, -1
+  %2 = call i32 @llvm.ctlz.i32(i32 %1, i1 false)
+  ret i32 %2
+}
+
+; CHECK: count_leading_1p:
+; CHECK: cl1(r1:0)
+define i32 @count_leading_1p(i64 %p) #0 {
+  %1 = xor i64 %p, -1
+  %2 = call i64 @llvm.ctlz.i64(i64 %1, i1 false)
+  %3 = trunc i64 %2 to i32
+  ret i32 %3
+}
+
+
+
+; CHECK: count_trailing_0:
+; CHECK: ct0(r0)
+define i32 @count_trailing_0(i32 %p) #0 {
+  %1 = call i32 @llvm.cttz.i32(i32 %p, i1 false)
+  ret i32 %1
+}
+
+; CHECK: count_trailing_0p:
+; CHECK: ct0(r1:0)
+define i32 @count_trailing_0p(i64 %p) #0 {
+  %1 = call i64 @llvm.cttz.i64(i64 %p, i1 false)
+  %2 = trunc i64 %1 to i32
+  ret i32 %2
+}
+
+; CHECK: count_trailing_1:
+; CHECK: ct1(r0)
+define i32 @count_trailing_1(i32 %p) #0 {
+  %1 = xor i32 %p, -1
+  %2 = call i32 @llvm.cttz.i32(i32 %1, i1 false)
+  ret i32 %2
+}
+
+; CHECK: count_trailing_1p:
+; CHECK: ct1(r1:0)
+define i32 @count_trailing_1p(i64 %p) #0 {
+  %1 = xor i64 %p, -1
+  %2 = call i64 @llvm.cttz.i64(i64 %1, i1 false)
+  %3 = trunc i64 %2 to i32
+  ret i32 %3
+}
+
+declare i32 @llvm.ctlz.i32(i32, i1)
+declare i64 @llvm.ctlz.i64(i64, i1)
+declare i32 @llvm.cttz.i32(i32, i1)
+declare i64 @llvm.cttz.i64(i64, i1)
+
+attributes #0 = { nounwind "target-cpu"="hexagonva55" }
+