From cfbb71dfb6464d9d442d6fc2fa0b76ded3981a53 Mon Sep 17 00:00:00 2001 From: Daniel Sanders Date: Wed, 9 Jul 2014 13:43:19 +0000 Subject: [PATCH] [mips] clz is defined to give 32 for zero. Similarly, dclz gives 64. 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 llvm-svn: 212618 --- clang/lib/Basic/Targets.cpp | 2 ++ clang/test/CodeGen/mips-count-builtins.c | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 clang/test/CodeGen/mips-count-builtins.c diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp index f048fa8..75e154d 100644 --- a/clang/lib/Basic/Targets.cpp +++ b/clang/lib/Basic/Targets.cpp @@ -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/clang/test/CodeGen/mips-count-builtins.c b/clang/test/CodeGen/mips-count-builtins.c new file mode 100644 index 0000000..7c9a257 --- /dev/null +++ b/clang/test/CodeGen/mips-count-builtins.c @@ -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) +} -- 2.7.4