Author: Nick Desaulniers Date: 2021-05-17T11:05:31-07:00 New Revision: de579bae6eabd02b815e549776b8c680957a0769
URL: https://github.com/llvm/llvm-project/commit/de579bae6eabd02b815e549776b8c680957a0769 DIFF: https://github.com/llvm/llvm-project/commit/de579bae6eabd02b815e549776b8c680957a0769.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 (cherry picked from commit 8c72749bd92d35397e93908bc5a504d4cbcef1cb) 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 0190aca27b724..71692c7460155 100644 --- a/llvm/include/llvm/IR/Constant.h +++ b/llvm/include/llvm/IR/Constant.h @@ -214,6 +214,10 @@ class Constant : public User { /// both must either be scalars or vectors with the same element count. If no /// 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; }; } // end namespace llvm diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp index f73890d548f09..cc1ce4c65821f 100644 --- a/llvm/lib/Analysis/ConstantFolding.cpp +++ b/llvm/lib/Analysis/ConstantFolding.cpp @@ -1808,19 +1808,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(); @@ -1845,7 +1832,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 6fd205c654a8a..9f05917cf7cc8 100644 --- a/llvm/lib/IR/Constants.cpp +++ b/llvm/lib/IR/Constants.cpp @@ -803,6 +803,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 bfe8db83b0271..bb30c48127a0f 100644 --- a/llvm/lib/Transforms/Scalar/LowerConstantIntrinsics.cpp +++ b/llvm/lib/Transforms/Scalar/LowerConstantIntrinsics.cpp @@ -43,10 +43,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 } + +@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 +} _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits