diff --git a/llvm/lib/Transforms/Scalar/LowerConstantIntrinsics.cpp b/llvm/lib/Transforms/Scalar/LowerConstantIntrinsics.cpp --- a/llvm/lib/Transforms/Scalar/LowerConstantIntrinsics.cpp +++ b/llvm/lib/Transforms/Scalar/LowerConstantIntrinsics.cpp @@ -45,10 +45,18 @@ "Number of 'objectsize' intrinsic calls handled"); static Value *lowerIsConstantIntrinsic(IntrinsicInst *II) { - Value *Op = II->getOperand(0); - - return isa(Op) ? ConstantInt::getTrue(II->getType()) - : ConstantInt::getFalse(II->getType()); + SmallVector WorkList; + WorkList.push_back(II->getOperand(0)); + while (WorkList.size()) { + Value *V = WorkList.back(); + if (!isa(V) || isa(V)) + return ConstantInt::getFalse(II->getType()); + WorkList.pop_back(); + if (auto *CA = dyn_cast(V)) + for (Value *Op : CA->operands()) + WorkList.push_back(Op); + } + return ConstantInt::getTrue(II->getType()); } static bool replaceConditionalBranchesOnConstant(Instruction *II, diff --git a/llvm/test/Transforms/LowerConstantIntrinsics/constant-intrinsics.ll b/llvm/test/Transforms/LowerConstantIntrinsics/constant-intrinsics.ll --- a/llvm/test/Transforms/LowerConstantIntrinsics/constant-intrinsics.ll +++ b/llvm/test/Transforms/LowerConstantIntrinsics/constant-intrinsics.ll @@ -112,3 +112,26 @@ ret i1 %res6 } + +@real_mode_blob_end = external dso_local global [0 x i8], align 1 +define i1 @global_array() { +; CHECK-LABEL: @global_array( +; CHECK-NEXT: ret i1 false + %1 = call i1 @llvm.is.constant.i64(i64 ptrtoint ([0 x i8]* @real_mode_blob_end to i64)) + ret i1 %1 +} + +define i1 @undef1() { +; CHECK-LABEL: undef1( +; CHECK-NEXT: ret i1 false + %1 = call i1 @llvm.is.constant.i64(i64 undef) + ret i1 %1 +} + +@undef_array = dso_local global [2 x i8] [i8 42, i8 undef] +define i1 @undef2() { +; CHECK-LABEL: undef2( +; CHECK-NEXT: ret i1 false + %1 = call i1 @llvm.is.constant.i64(i64 ptrtoint ([2 x i8]* @undef_array to i64)) + ret i1 %1 +}