[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