[LLVM][ConstantFold] Undefined values are not constant (#130713)
llvm.is.constant (and therefore Clang's __builtin_constant_p()) need to report undefined values as non-constant or future DCE choices end up making no sense. This was encountered while building the Linux kernel which uses __builtin_constant_p() while trying to evaluate if it is safe to use a compile-time constant resolution for string lengths or if it must kick over to a full runtime call to strlen(). Obviously an undefined variable cannot be known at compile-time, so __builtin_constant_p() needs to return false. This change will also mean that Clang will match GCC's behavior under the same conditions. Fixes #130649
This commit is contained in:
parent
dd181af950
commit
ea2e66aa8b
@ -841,6 +841,8 @@ Constant *Constant::mergeUndefsWith(Constant *C, Constant *Other) {
|
||||
}
|
||||
|
||||
bool Constant::isManifestConstant() const {
|
||||
if (isa<UndefValue>(this))
|
||||
return false;
|
||||
if (isa<ConstantData>(this))
|
||||
return true;
|
||||
if (isa<ConstantAggregate>(this) || isa<ConstantExpr>(this)) {
|
||||
|
@ -120,3 +120,21 @@ define i1 @global_array() {
|
||||
%1 = call i1 @llvm.is.constant.i64(i64 ptrtoint (ptr @real_mode_blob_end to i64))
|
||||
ret i1 %1
|
||||
}
|
||||
|
||||
;; Ensure that is.constant of undef gets lowered reasonably to "false" in
|
||||
;; optimized codegen: specifically that the "true" branch is eliminated.
|
||||
;; CHECK-NOT: tail call i32 @subfun_1()
|
||||
;; CHECK: tail call i32 @subfun_2()
|
||||
;; CHECK-NOT: tail call i32 @subfun_1()
|
||||
define i32 @test_undef_branch() nounwind {
|
||||
%v = call i1 @llvm.is.constant.i32(i32 undef)
|
||||
br i1 %v, label %True, label %False
|
||||
|
||||
True:
|
||||
%call1 = tail call i32 @subfun_1()
|
||||
ret i32 %call1
|
||||
|
||||
False:
|
||||
%call2 = tail call i32 @subfun_2()
|
||||
ret i32 %call2
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user