Skip to content

Commit 8c72749

Browse files
[LowerConstantIntrinsics] reuse isManifestLogic from ConstantFolding
GlobalVariables are Constants, yet should not unconditionally be considered true for __builtin_constant_p. Via the LangRef https://llvm.org/docs/LangRef.html#llvm-is-constant-intrinsic: This intrinsic generates no code. If its argument is known to be a manifest compile-time constant value, then the intrinsic will be converted to a constant true value. Otherwise, it will be converted to a constant false value. In particular, note that if the argument is a constant expression which refers to a global (the address of which _is_ a constant, but not manifest during the compile), then the intrinsic evaluates to false. Move isManifestConstant from ConstantFolding to be a method of Constant so that we can reuse the same logic in LowerConstantIntrinsics. pr/41459 Reviewed By: rsmith, george.burgess.iv Differential Revision: https://reviews.llvm.org/D102367
1 parent bede752 commit 8c72749

File tree

5 files changed

+29
-18
lines changed

5 files changed

+29
-18
lines changed

llvm/include/llvm/IR/Constant.h

+4
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,10 @@ class Constant : public User {
217217
/// changes are made, the constant C is returned.
218218
static Constant *mergeUndefsWith(Constant *C, Constant *Other);
219219

220+
/// Return true if a constant is ConstantData or a ConstantAggregate or
221+
/// ConstantExpr that contain only ConstantData.
222+
bool isManifestConstant() const;
223+
220224
private:
221225
enum PossibleRelocationsTy {
222226
/// This constant requires no relocations. That is, it holds simple

llvm/lib/Analysis/ConstantFolding.cpp

+1-14
Original file line numberDiff line numberDiff line change
@@ -1806,19 +1806,6 @@ double getValueAsDouble(ConstantFP *Op) {
18061806
return APF.convertToDouble();
18071807
}
18081808

1809-
static bool isManifestConstant(const Constant *c) {
1810-
if (isa<ConstantData>(c)) {
1811-
return true;
1812-
} else if (isa<ConstantAggregate>(c) || isa<ConstantExpr>(c)) {
1813-
for (const Value *subc : c->operand_values()) {
1814-
if (!isManifestConstant(cast<Constant>(subc)))
1815-
return false;
1816-
}
1817-
return true;
1818-
}
1819-
return false;
1820-
}
1821-
18221809
static bool getConstIntOrUndef(Value *Op, const APInt *&C) {
18231810
if (auto *CI = dyn_cast<ConstantInt>(Op)) {
18241811
C = &CI->getValue();
@@ -1843,7 +1830,7 @@ static Constant *ConstantFoldScalarCall1(StringRef Name,
18431830
// We know we have a "Constant" argument. But we want to only
18441831
// return true for manifest constants, not those that depend on
18451832
// constants with unknowable values, e.g. GlobalValue or BlockAddress.
1846-
if (isManifestConstant(Operands[0]))
1833+
if (Operands[0]->isManifestConstant())
18471834
return ConstantInt::getTrue(Ty->getContext());
18481835
return nullptr;
18491836
}

llvm/lib/IR/Constants.cpp

+12
Original file line numberDiff line numberDiff line change
@@ -823,6 +823,18 @@ Constant *Constant::mergeUndefsWith(Constant *C, Constant *Other) {
823823
return C;
824824
}
825825

826+
bool Constant::isManifestConstant() const {
827+
if (isa<ConstantData>(this))
828+
return true;
829+
if (isa<ConstantAggregate>(this) || isa<ConstantExpr>(this)) {
830+
for (const Value *Op : operand_values())
831+
if (!cast<Constant>(Op)->isManifestConstant())
832+
return false;
833+
return true;
834+
}
835+
return false;
836+
}
837+
826838
//===----------------------------------------------------------------------===//
827839
// ConstantInt
828840
//===----------------------------------------------------------------------===//

llvm/lib/Transforms/Scalar/LowerConstantIntrinsics.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,10 @@ STATISTIC(ObjectSizeIntrinsicsHandled,
4545
"Number of 'objectsize' intrinsic calls handled");
4646

4747
static Value *lowerIsConstantIntrinsic(IntrinsicInst *II) {
48-
Value *Op = II->getOperand(0);
49-
50-
return isa<Constant>(Op) ? ConstantInt::getTrue(II->getType())
51-
: ConstantInt::getFalse(II->getType());
48+
if (auto *C = dyn_cast<Constant>(II->getOperand(0)))
49+
if (C->isManifestConstant())
50+
return ConstantInt::getTrue(II->getType());
51+
return ConstantInt::getFalse(II->getType());
5252
}
5353

5454
static bool replaceConditionalBranchesOnConstant(Instruction *II,

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

+8
Original file line numberDiff line numberDiff line change
@@ -112,3 +112,11 @@ define i1 @test_various_types(i256 %int, float %float, <2 x i64> %vec, {i32, i32
112112

113113
ret i1 %res6
114114
}
115+
116+
@real_mode_blob_end = external dso_local global [0 x i8], align 1
117+
define i1 @global_array() {
118+
; CHECK-LABEL: @global_array(
119+
; CHECK-NEXT: ret i1 false
120+
%1 = call i1 @llvm.is.constant.i64(i64 ptrtoint ([0 x i8]* @real_mode_blob_end to i64))
121+
ret i1 %1
122+
}

0 commit comments

Comments
 (0)