]> granicus.if.org Git - clang/commitdiff
[mips] clz is defined to give 32 for zero. Similarly, dclz gives 64.
authorDaniel Sanders <daniel.sanders@imgtec.com>
Wed, 9 Jul 2014 13:43:19 +0000 (13:43 +0000)
committerDaniel Sanders <daniel.sanders@imgtec.com>
Wed, 9 Jul 2014 13:43:19 +0000 (13:43 +0000)
Summary:
While debugging another issue, I noticed that Mips currently specifies that the
count leading zero builtins are undefined when the input is zero. The
architecture specifications say that the clz and dclz instructions write 32 or
64 respectively when given zero.

This doesn't fix any bugs that I'm aware of but it may improve optimisation in
some cases.

Differential Revision: http://reviews.llvm.org/D4431

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@212618 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Basic/Targets.cpp
test/CodeGen/mips-count-builtins.c [new file with mode: 0644]

index f048fa822742c19e87ca32a88946a79a1df75c79..75e154d7d5eb681bd988b593286a5297bf3f8125 100644 (file)
@@ -5513,6 +5513,8 @@ public:
     if (RegNo == 1) return 5;
     return -1;
   }
+
+  bool isCLZForZeroUndef() const override { return false; }
 };
 
 const Builtin::Info MipsTargetInfoBase::BuiltinInfo[] = {
diff --git a/test/CodeGen/mips-count-builtins.c b/test/CodeGen/mips-count-builtins.c
new file mode 100644 (file)
index 0000000..7c9a257
--- /dev/null
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 %s -triple mips-unknown-linux-gnu -emit-llvm -o - | FileCheck %s
+//
+// Test that the ctlz and cttz builtins are defined for zero.
+// Based on count-builtin.c
+
+int leading, trailing, pop;
+
+void test_i16(short P) {
+  leading = __builtin_clzs(P);
+  trailing = __builtin_ctzs(P);
+
+// CHECK: @test_i16
+// CHECK: call i16 @llvm.ctlz.i16(i16 {{.*}}, i1 false)
+// CHECK: call i16 @llvm.cttz.i16(i16 {{.*}}, i1 false)
+}
+
+void test_i32(int P) {
+  leading = __builtin_clz(P);
+  trailing = __builtin_ctz(P);
+
+// CHECK: @test_i32
+// CHECK: call i32 @llvm.ctlz.i32(i32 {{.*}}, i1 false)
+// CHECK: call i32 @llvm.cttz.i32(i32 {{.*}}, i1 false)
+}
+
+void test_i64(float P) {
+  leading = __builtin_clzll(P);
+  trailing = __builtin_ctzll(P);
+// CHECK: @test_i64
+// CHECK: call i64 @llvm.ctlz.i64(i64 {{.*}}, i1 false)
+// CHECK: call i64 @llvm.cttz.i64(i64 {{.*}}, i1 false)
+}