forked from OSchip/llvm-project
ConstantFolding: Add a missing folding that leads to a miscompile.
We use constant folding to see if an intrinsic evaluates to the same value as a constant that we know. If we don't take the undefinedness into account we get a value that doesn't match the actual implementation, and miscompiled code. This was uncovered by Chandler's simplifycfg changes. llvm-svn: 173356
This commit is contained in:
parent
cbc86bcbb5
commit
435eba09b7
|
@ -1474,12 +1474,12 @@ llvm::ConstantFoldCall(Function *F, ArrayRef<Constant *> Operands,
|
|||
return ConstantStruct::get(cast<StructType>(F->getReturnType()), Ops);
|
||||
}
|
||||
case Intrinsic::cttz:
|
||||
// FIXME: This should check for Op2 == 1, and become unreachable if
|
||||
// Op1 == 0.
|
||||
if (Op2->isOne() && Op1->isZero()) // cttz(0, 1) is undef.
|
||||
return UndefValue::get(Ty);
|
||||
return ConstantInt::get(Ty, Op1->getValue().countTrailingZeros());
|
||||
case Intrinsic::ctlz:
|
||||
// FIXME: This should check for Op2 == 1, and become unreachable if
|
||||
// Op1 == 0.
|
||||
if (Op2->isOne() && Op1->isZero()) // ctlz(0, 1) is undef.
|
||||
return UndefValue::get(Ty);
|
||||
return ConstantInt::get(Ty, Op1->getValue().countLeadingZeros());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,6 @@
|
|||
declare i13 @llvm.cttz.i13(i13, i1)
|
||||
|
||||
define i13 @test() {
|
||||
%X = call i13 @llvm.cttz.i13(i13 0, i1 true)
|
||||
%X = call i13 @llvm.cttz.i13(i13 0, i1 false)
|
||||
ret i13 %X
|
||||
}
|
||||
|
|
|
@ -220,3 +220,39 @@ define i32 @cttz_simplify1b(i32 %x) nounwind readnone ssp {
|
|||
; CHECK: @cttz_simplify1b
|
||||
; CHECK-NEXT: ret i32 0
|
||||
}
|
||||
|
||||
define i32 @ctlz_undef(i32 %Value) nounwind {
|
||||
%ctlz = call i32 @llvm.ctlz.i32(i32 0, i1 true)
|
||||
ret i32 %ctlz
|
||||
|
||||
; CHECK: @ctlz_undef
|
||||
; CHECK-NEXT: ret i32 undef
|
||||
}
|
||||
|
||||
define i32 @cttz_undef(i32 %Value) nounwind {
|
||||
%cttz = call i32 @llvm.cttz.i32(i32 0, i1 true)
|
||||
ret i32 %cttz
|
||||
|
||||
; CHECK: @cttz_undef
|
||||
; CHECK-NEXT: ret i32 undef
|
||||
}
|
||||
|
||||
define i32 @ctlz_select(i32 %Value) nounwind {
|
||||
%tobool = icmp ne i32 %Value, 0
|
||||
%ctlz = call i32 @llvm.ctlz.i32(i32 %Value, i1 true)
|
||||
%s = select i1 %tobool, i32 %ctlz, i32 32
|
||||
ret i32 %s
|
||||
|
||||
; CHECK: @ctlz_select
|
||||
; CHECK: select i1 %tobool, i32 %ctlz, i32 32
|
||||
}
|
||||
|
||||
define i32 @cttz_select(i32 %Value) nounwind {
|
||||
%tobool = icmp ne i32 %Value, 0
|
||||
%cttz = call i32 @llvm.cttz.i32(i32 %Value, i1 true)
|
||||
%s = select i1 %tobool, i32 %cttz, i32 32
|
||||
ret i32 %s
|
||||
|
||||
; CHECK: @cttz_select
|
||||
; CHECK: select i1 %tobool, i32 %cttz, i32 32
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue