SimplifyLibcalls: The return value of ffsll is always i32, even when the input is zero.

Fixes PR13028.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@166313 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Benjamin Kramer 2012-10-19 20:43:44 +00:00
parent 28ce1cc183
commit 0aae4bd0fc
2 changed files with 14 additions and 5 deletions

View File

@ -772,8 +772,8 @@ struct FFSOpt : public LibCallOptimization {
// Constant fold.
if (ConstantInt *CI = dyn_cast<ConstantInt>(Op)) {
if (CI->getValue() == 0) // ffs(0) -> 0.
return Constant::getNullValue(CI->getType());
if (CI->isZero()) // ffs(0) -> 0.
return B.getInt32(0);
// ffs(c) -> cttz(c)+1
return B.getInt32(CI->getValue().countTrailingZeros() + 1);
}

View File

@ -1,6 +1,7 @@
; Test that the ToAsciiOptimizer works correctly
; RUN: opt < %s -simplify-libcalls -S | \
; RUN: not grep "call.*@ffs"
; Test that FFSOpt works correctly
; RUN: opt < %s -simplify-libcalls -S | FileCheck %s
; CHECK-NOT: call{{.*}}@ffs
@non_const = external global i32 ; <i32*> [#uses=1]
@ -34,3 +35,11 @@ define i32 @a(i64) nounwind {
%2 = call i32 @ffsll(i64 %0) ; <i32> [#uses=1]
ret i32 %2
}
; PR13028
define i32 @b() nounwind {
%ffs = call i32 @ffsll(i64 0)
ret i32 %ffs
; CHECK: @b
; CHECK-NEXT: ret i32 0
}