[llvm] 8c72749 - [LowerConstantIntrinsics] reuse isManifestLogic from ConstantFolding
Nick Desaulniers via llvm-commits
llvm-commits at lists.llvm.org
Fri May 14 15:35:42 PDT 2021
Author: Nick Desaulniers
Date: 2021-05-14T15:35:21-07:00
New Revision: 8c72749bd92d35397e93908bc5a504d4cbcef1cb
URL: https://github.com/llvm/llvm-project/commit/8c72749bd92d35397e93908bc5a504d4cbcef1cb
DIFF: https://github.com/llvm/llvm-project/commit/8c72749bd92d35397e93908bc5a504d4cbcef1cb.diff
LOG: [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
Added:
Modified:
llvm/include/llvm/IR/Constant.h
llvm/lib/Analysis/ConstantFolding.cpp
llvm/lib/IR/Constants.cpp
llvm/lib/Transforms/Scalar/LowerConstantIntrinsics.cpp
llvm/test/Transforms/LowerConstantIntrinsics/constant-intrinsics.ll
Removed:
################################################################################
diff --git a/llvm/include/llvm/IR/Constant.h b/llvm/include/llvm/IR/Constant.h
index 959d0e716d251..4e2022b36e302 100644
--- a/llvm/include/llvm/IR/Constant.h
+++ b/llvm/include/llvm/IR/Constant.h
@@ -217,6 +217,10 @@ class Constant : public User {
/// changes are made, the constant C is returned.
static Constant *mergeUndefsWith(Constant *C, Constant *Other);
+ /// Return true if a constant is ConstantData or a ConstantAggregate or
+ /// ConstantExpr that contain only ConstantData.
+ bool isManifestConstant() const;
+
private:
enum PossibleRelocationsTy {
/// This constant requires no relocations. That is, it holds simple
diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index 0b97b823ce048..d09e4b8d20846 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -1806,19 +1806,6 @@ double getValueAsDouble(ConstantFP *Op) {
return APF.convertToDouble();
}
-static bool isManifestConstant(const Constant *c) {
- if (isa<ConstantData>(c)) {
- return true;
- } else if (isa<ConstantAggregate>(c) || isa<ConstantExpr>(c)) {
- for (const Value *subc : c->operand_values()) {
- if (!isManifestConstant(cast<Constant>(subc)))
- return false;
- }
- return true;
- }
- return false;
-}
-
static bool getConstIntOrUndef(Value *Op, const APInt *&C) {
if (auto *CI = dyn_cast<ConstantInt>(Op)) {
C = &CI->getValue();
@@ -1843,7 +1830,7 @@ static Constant *ConstantFoldScalarCall1(StringRef Name,
// We know we have a "Constant" argument. But we want to only
// return true for manifest constants, not those that depend on
// constants with unknowable values, e.g. GlobalValue or BlockAddress.
- if (isManifestConstant(Operands[0]))
+ if (Operands[0]->isManifestConstant())
return ConstantInt::getTrue(Ty->getContext());
return nullptr;
}
diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp
index 7d93d41a398c9..54b0a7d4826e3 100644
--- a/llvm/lib/IR/Constants.cpp
+++ b/llvm/lib/IR/Constants.cpp
@@ -823,6 +823,18 @@ Constant *Constant::mergeUndefsWith(Constant *C, Constant *Other) {
return C;
}
+bool Constant::isManifestConstant() const {
+ if (isa<ConstantData>(this))
+ return true;
+ if (isa<ConstantAggregate>(this) || isa<ConstantExpr>(this)) {
+ for (const Value *Op : operand_values())
+ if (!cast<Constant>(Op)->isManifestConstant())
+ return false;
+ return true;
+ }
+ return false;
+}
+
//===----------------------------------------------------------------------===//
// ConstantInt
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Transforms/Scalar/LowerConstantIntrinsics.cpp b/llvm/lib/Transforms/Scalar/LowerConstantIntrinsics.cpp
index 0890437fd90ca..2ba84440cb7d3 100644
--- a/llvm/lib/Transforms/Scalar/LowerConstantIntrinsics.cpp
+++ b/llvm/lib/Transforms/Scalar/LowerConstantIntrinsics.cpp
@@ -45,10 +45,10 @@ STATISTIC(ObjectSizeIntrinsicsHandled,
"Number of 'objectsize' intrinsic calls handled");
static Value *lowerIsConstantIntrinsic(IntrinsicInst *II) {
- Value *Op = II->getOperand(0);
-
- return isa<Constant>(Op) ? ConstantInt::getTrue(II->getType())
- : ConstantInt::getFalse(II->getType());
+ if (auto *C = dyn_cast<Constant>(II->getOperand(0)))
+ if (C->isManifestConstant())
+ return ConstantInt::getTrue(II->getType());
+ return ConstantInt::getFalse(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
index b2c98d2049cd3..e19dce1b55433 100644
--- a/llvm/test/Transforms/LowerConstantIntrinsics/constant-intrinsics.ll
+++ b/llvm/test/Transforms/LowerConstantIntrinsics/constant-intrinsics.ll
@@ -112,3 +112,11 @@ define i1 @test_various_types(i256 %int, float %float, <2 x i64> %vec, {i32, i32
ret i1 %res6
}
+
+ at 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
+}
More information about the llvm-commits
mailing list