[llvm] 20d9c51 - [ConstantFold] Check for uniform value before reinterpret load
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Fri Jan 14 01:23:45 PST 2022
Author: Nikita Popov
Date: 2022-01-14T10:18:02+01:00
New Revision: 20d9c51dc0d11c8bd1c8135aef7816b9cac31990
URL: https://github.com/llvm/llvm-project/commit/20d9c51dc0d11c8bd1c8135aef7816b9cac31990
DIFF: https://github.com/llvm/llvm-project/commit/20d9c51dc0d11c8bd1c8135aef7816b9cac31990.diff
LOG: [ConstantFold] Check for uniform value before reinterpret load
The reinterpret load code will convert undef values into zero.
Check the uniform value case before it to produce a better result
for all-undef initializers.
However, the uniform value handling will return the uniform value
even if the access is out of bounds, while the reinterpret load
code will return undef. Add an explicit check to retain the
previous result in this case.
Added:
Modified:
llvm/lib/Analysis/ConstantFolding.cpp
llvm/test/Transforms/InstSimplify/ConstProp/loads.ll
Removed:
################################################################################
diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index 497d0efd27195..b504d3310f575 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -669,14 +669,23 @@ Constant *llvm::ConstantFoldLoadFromConst(Constant *C, Type *Ty,
if (Constant *Result = ConstantFoldLoadThroughBitcast(AtOffset, Ty, DL))
return Result;
+ // Explicitly check for out-of-bounds access, so we return undef even if the
+ // constant is a uniform value.
+ TypeSize Size = DL.getTypeAllocSize(C->getType());
+ if (!Size.isScalable() && Offset.sge(Size.getFixedSize()))
+ return UndefValue::get(Ty);
+
+ // Try an offset-independent fold of a uniform value.
+ if (Constant *Result = ConstantFoldLoadFromUniformValue(C, Ty))
+ return Result;
+
// Try hard to fold loads from bitcasted strange and non-type-safe things.
if (Offset.getMinSignedBits() <= 64)
if (Constant *Result =
FoldReinterpretLoadFromConst(C, Ty, Offset.getSExtValue(), DL))
return Result;
- // Try an offset-independent fold of a uniform value.
- return ConstantFoldLoadFromUniformValue(C, Ty);
+ return nullptr;
}
Constant *llvm::ConstantFoldLoadFromConst(Constant *C, Type *Ty,
diff --git a/llvm/test/Transforms/InstSimplify/ConstProp/loads.ll b/llvm/test/Transforms/InstSimplify/ConstProp/loads.ll
index 08605d9b6460f..afdc9980ab4f9 100644
--- a/llvm/test/Transforms/InstSimplify/ConstProp/loads.ll
+++ b/llvm/test/Transforms/InstSimplify/ConstProp/loads.ll
@@ -331,7 +331,7 @@ define i32 @load_padding() {
; Same as the previous case, but with an all-undef initializer.
define i32 @load_all_undef() {
; CHECK-LABEL: @load_all_undef(
-; CHECK-NEXT: ret i32 0
+; CHECK-NEXT: ret i32 undef
;
%v = load i32, i32* getelementptr (i32, i32* bitcast ({ i32, [4 x i8] }* @g_all_undef to i32*), i64 1)
ret i32 %v
More information about the llvm-commits
mailing list