[PATCH] D112260: [Loads] Use more powerful constant folding API

Nikita Popov via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 21 12:06:29 PDT 2021


nikic created this revision.
nikic added a reviewer: aeubanks.
Herald added a subscriber: hiraditya.
nikic requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

This follows up on D111023 <https://reviews.llvm.org/D111023> by exporting the generic "load value from constant at given offset as given type" and using it in the store to load forwarding code. We now need to make sure that the load size is smaller than the store size, previously this was implicitly ensured by ConstantFoldLoadThroughBitcast().


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D112260

Files:
  llvm/include/llvm/Analysis/ConstantFolding.h
  llvm/lib/Analysis/ConstantFolding.cpp
  llvm/lib/Analysis/Loads.cpp
  llvm/test/Transforms/InstCombine/load-store-forward.ll


Index: llvm/test/Transforms/InstCombine/load-store-forward.ll
===================================================================
--- llvm/test/Transforms/InstCombine/load-store-forward.ll
+++ llvm/test/Transforms/InstCombine/load-store-forward.ll
@@ -6,11 +6,13 @@
 ; but is non-trivial.
 
 define i8 @load_smaller_int(i16* %p) {
-; CHECK-LABEL: @load_smaller_int(
-; CHECK-NEXT:    store i16 258, i16* [[P:%.*]], align 2
-; CHECK-NEXT:    [[P2:%.*]] = bitcast i16* [[P]] to i8*
-; CHECK-NEXT:    [[LOAD:%.*]] = load i8, i8* [[P2]], align 1
-; CHECK-NEXT:    ret i8 [[LOAD]]
+; LITTLE-LABEL: @load_smaller_int(
+; LITTLE-NEXT:    store i16 258, i16* [[P:%.*]], align 2
+; LITTLE-NEXT:    ret i8 2
+;
+; BIG-LABEL: @load_smaller_int(
+; BIG-NEXT:    store i16 258, i16* [[P:%.*]], align 2
+; BIG-NEXT:    ret i8 1
 ;
   store i16 258, i16* %p
   %p2 = bitcast i16* %p to i8*
Index: llvm/lib/Analysis/Loads.cpp
===================================================================
--- llvm/lib/Analysis/Loads.cpp
+++ llvm/lib/Analysis/Loads.cpp
@@ -511,8 +511,11 @@
     if (CastInst::isBitOrNoopPointerCastable(Val->getType(), AccessTy, DL))
       return Val;
 
-    if (auto *C = dyn_cast<Constant>(Val))
-      return ConstantFoldLoadThroughBitcast(C, AccessTy, DL);
+    TypeSize StoreSize = DL.getTypeStoreSize(Val->getType());
+    TypeSize LoadSize = DL.getTypeStoreSize(AccessTy);
+    if (TypeSize::isKnownLE(LoadSize, StoreSize))
+      if (auto *C = dyn_cast<Constant>(Val))
+        return ConstantFoldLoadFromConst(C, AccessTy, DL);
   }
 
   return nullptr;
Index: llvm/lib/Analysis/ConstantFolding.cpp
===================================================================
--- llvm/lib/Analysis/ConstantFolding.cpp
+++ llvm/lib/Analysis/ConstantFolding.cpp
@@ -668,8 +668,11 @@
   return C;
 }
 
-Constant *ConstantFoldLoadFromConst(Constant *C, Type *Ty, const APInt &Offset,
-                                    const DataLayout &DL) {
+} // end anonymous namespace
+
+Constant *llvm::ConstantFoldLoadFromConst(Constant *C, Type *Ty,
+                                          const APInt &Offset,
+                                          const DataLayout &DL) {
   if (Constant *AtOffset = getConstantAtOffset(C, Offset, DL))
     if (Constant *Result = ConstantFoldLoadThroughBitcast(AtOffset, Ty, DL))
       return Result;
@@ -681,7 +684,10 @@
   return nullptr;
 }
 
-} // end anonymous namespace
+Constant *llvm::ConstantFoldLoadFromConst(Constant *C, Type *Ty,
+                                          const DataLayout &DL) {
+  return ConstantFoldLoadFromConst(C, Ty, APInt(64, 0), DL);
+}
 
 Constant *llvm::ConstantFoldLoadFromConstPtr(Constant *C, Type *Ty,
                                              const DataLayout &DL) {
Index: llvm/include/llvm/Analysis/ConstantFolding.h
===================================================================
--- llvm/include/llvm/Analysis/ConstantFolding.h
+++ llvm/include/llvm/Analysis/ConstantFolding.h
@@ -128,6 +128,17 @@
 Constant *ConstantFoldShuffleVectorInstruction(Constant *V1, Constant *V2,
                                                ArrayRef<int> Mask);
 
+/// Extract value of C at the given Offset reinterpreted as Ty. If bits past
+/// the end of C are accessed, they are assumed to be poison and may take any
+/// value.
+Constant *ConstantFoldLoadFromConst(Constant *C, Type *Ty, const APInt &Offset,
+                                    const DataLayout &DL);
+
+/// Extract value of C reinterpreted as Ty. Same as previous API with zero
+/// offset.
+Constant *ConstantFoldLoadFromConst(Constant *C, Type *Ty,
+                                    const DataLayout &DL);
+
 /// ConstantFoldLoadFromConstPtr - Return the value that a load from C would
 /// produce if it is constant and determinable.  If this is not determinable,
 /// return null.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D112260.381352.patch
Type: text/x-patch
Size: 3839 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20211021/d7c039a2/attachment.bin>


More information about the llvm-commits mailing list