[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.
This commit is contained in:
Nikita Popov 2022-01-14 10:07:37 +01:00
parent e7ce6acc83
commit 20d9c51dc0
2 changed files with 12 additions and 3 deletions

View File

@ -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,

View File

@ -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