Skip to content

Commit ea2e66a

Browse files
authored
[LLVM][ConstantFold] Undefined values are not constant (llvm#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 llvm#130649
1 parent dd181af commit ea2e66a

File tree

2 files changed

+20
-0
lines changed

2 files changed

+20
-0
lines changed

llvm/lib/IR/Constants.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -841,6 +841,8 @@ Constant *Constant::mergeUndefsWith(Constant *C, Constant *Other) {
841841
}
842842

843843
bool Constant::isManifestConstant() const {
844+
if (isa<UndefValue>(this))
845+
return false;
844846
if (isa<ConstantData>(this))
845847
return true;
846848
if (isa<ConstantAggregate>(this) || isa<ConstantExpr>(this)) {

llvm/test/Transforms/LowerConstantIntrinsics/constant-intrinsics.ll

+18
Original file line numberDiff line numberDiff line change
@@ -120,3 +120,21 @@ define i1 @global_array() {
120120
%1 = call i1 @llvm.is.constant.i64(i64 ptrtoint (ptr @real_mode_blob_end to i64))
121121
ret i1 %1
122122
}
123+
124+
;; Ensure that is.constant of undef gets lowered reasonably to "false" in
125+
;; optimized codegen: specifically that the "true" branch is eliminated.
126+
;; CHECK-NOT: tail call i32 @subfun_1()
127+
;; CHECK: tail call i32 @subfun_2()
128+
;; CHECK-NOT: tail call i32 @subfun_1()
129+
define i32 @test_undef_branch() nounwind {
130+
%v = call i1 @llvm.is.constant.i32(i32 undef)
131+
br i1 %v, label %True, label %False
132+
133+
True:
134+
%call1 = tail call i32 @subfun_1()
135+
ret i32 %call1
136+
137+
False:
138+
%call2 = tail call i32 @subfun_2()
139+
ret i32 %call2
140+
}

0 commit comments

Comments
 (0)