[llvm] r275345 - [ConstantFolding] Extend FoldReinterpretLoadFromConstPtr to handle negative offsets

David Majnemer via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 13 16:33:08 PDT 2016


Author: majnemer
Date: Wed Jul 13 18:33:07 2016
New Revision: 275345

URL: http://llvm.org/viewvc/llvm-project?rev=275345&view=rev
Log:
[ConstantFolding] Extend FoldReinterpretLoadFromConstPtr to handle negative offsets

Treat loads which clip before the start of a global initializer the same
way we treat clipping beyond the end of the initializer: use zeros.

Modified:
    llvm/trunk/lib/Analysis/ConstantFolding.cpp
    llvm/trunk/test/Transforms/InstSimplify/load.ll

Modified: llvm/trunk/lib/Analysis/ConstantFolding.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ConstantFolding.cpp?rev=275345&r1=275344&r2=275345&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/ConstantFolding.cpp (original)
+++ llvm/trunk/lib/Analysis/ConstantFolding.cpp Wed Jul 13 18:33:07 2016
@@ -442,8 +442,8 @@ Constant *FoldReinterpretLoadFromConstPt
     return nullptr;
 
   GlobalValue *GVal;
-  APInt Offset;
-  if (!IsConstantOffsetFromGlobal(C, GVal, Offset, DL))
+  APInt OffsetAI;
+  if (!IsConstantOffsetFromGlobal(C, GVal, OffsetAI, DL))
     return nullptr;
 
   auto *GV = dyn_cast<GlobalVariable>(GVal);
@@ -451,19 +451,29 @@ Constant *FoldReinterpretLoadFromConstPt
       !GV->getInitializer()->getType()->isSized())
     return nullptr;
 
-  // If we're loading off the beginning of the global, some bytes may be valid,
-  // but we don't try to handle this.
-  if (Offset.isNegative())
-    return nullptr;
+  int64_t Offset = OffsetAI.getSExtValue();
+  int64_t InitializerSize = DL.getTypeAllocSize(GV->getInitializer()->getType());
+
+  // If we're not accessing anything in this constant, the result is undefined.
+  if (Offset + BytesLoaded <= 0)
+    return UndefValue::get(IntType);
 
   // If we're not accessing anything in this constant, the result is undefined.
-  if (Offset.getZExtValue() >=
-      DL.getTypeAllocSize(GV->getInitializer()->getType()))
+  if (Offset >= InitializerSize)
     return UndefValue::get(IntType);
 
   unsigned char RawBytes[32] = {0};
-  if (!ReadDataFromGlobal(GV->getInitializer(), Offset.getZExtValue(), RawBytes,
-                          BytesLoaded, DL))
+  unsigned char *CurPtr = RawBytes;
+  unsigned BytesLeft = BytesLoaded;
+
+  // If we're loading off the beginning of the global, some bytes may be valid.
+  if (Offset < 0) {
+    CurPtr += -Offset;
+    BytesLeft += Offset;
+    Offset = 0;
+  }
+
+  if (!ReadDataFromGlobal(GV->getInitializer(), Offset, CurPtr, BytesLeft, DL))
     return nullptr;
 
   APInt ResultVal = APInt(IntType->getBitWidth(), 0);

Modified: llvm/trunk/test/Transforms/InstSimplify/load.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstSimplify/load.ll?rev=275345&r1=275344&r2=275345&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstSimplify/load.ll (original)
+++ llvm/trunk/test/Transforms/InstSimplify/load.ll Wed Jul 13 18:33:07 2016
@@ -20,3 +20,11 @@ define i32 @crash_on_undef() {
   ret i32 %load
 }
 
+ at GV = private constant [8 x i32] [i32 42, i32 43, i32 44, i32 45, i32 46, i32 47, i32 48, i32 49]
+
+define <8 x i32> @partial_load() {
+; CHECK-LABEL: @partial_load(
+; CHECK:         ret <8 x i32> <i32 0, i32 42, i32 43, i32 44, i32 45, i32 46, i32 47, i32 48>
+  %load = load <8 x i32>, <8 x i32>* bitcast (i32* getelementptr ([8 x i32], [8 x i32]* @GV, i64 0, i64 -1) to <8 x i32>*)
+  ret <8 x i32> %load
+}




More information about the llvm-commits mailing list