[llvm] 3a10fe2 - [Loads] Use more powerful constant folding API

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 22 09:34:10 PDT 2021


Author: Nikita Popov
Date: 2021-10-22T18:33:03+02:00
New Revision: 3a10fe2d893f3c112663d117a4802aacde3b378a

URL: https://github.com/llvm/llvm-project/commit/3a10fe2d893f3c112663d117a4802aacde3b378a
DIFF: https://github.com/llvm/llvm-project/commit/3a10fe2d893f3c112663d117a4802aacde3b378a.diff

LOG: [Loads] Use more powerful constant folding API

This follows up on 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().

Differential Revision: https://reviews.llvm.org/D112260

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/Analysis/ConstantFolding.h b/llvm/include/llvm/Analysis/ConstantFolding.h
index 62742fdf9a91..2cf4eddda77a 100644
--- a/llvm/include/llvm/Analysis/ConstantFolding.h
+++ b/llvm/include/llvm/Analysis/ConstantFolding.h
@@ -128,6 +128,17 @@ Constant *ConstantFoldExtractElementInstruction(Constant *Val, Constant *Idx);
 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.

diff  --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index 13cde289f72f..c761fdeb09b0 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -668,8 +668,11 @@ Constant *getConstantAtOffset(Constant *Base, APInt Offset,
   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 @@ Constant *ConstantFoldLoadFromConst(Constant *C, Type *Ty, const APInt &Offset,
   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) {

diff  --git a/llvm/lib/Analysis/Loads.cpp b/llvm/lib/Analysis/Loads.cpp
index 2e5f80d80015..1882e31a246a 100644
--- a/llvm/lib/Analysis/Loads.cpp
+++ b/llvm/lib/Analysis/Loads.cpp
@@ -511,8 +511,11 @@ static Value *getAvailableLoadStore(Instruction *Inst, const Value *Ptr,
     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;

diff  --git a/llvm/test/Transforms/InstCombine/load-store-forward.ll b/llvm/test/Transforms/InstCombine/load-store-forward.ll
index 3dac00c6280f..1f4c49376f9b 100644
--- a/llvm/test/Transforms/InstCombine/load-store-forward.ll
+++ b/llvm/test/Transforms/InstCombine/load-store-forward.ll
@@ -2,15 +2,14 @@
 ; RUN: opt -S -instcombine < %s | FileCheck %s --check-prefixes=CHECK,LITTLE
 ; RUN: opt -S -instcombine -data-layout="E" < %s | FileCheck %s --check-prefixes=CHECK,BIG
 
-; Some cases where store to load forwarding is principally possible,
-; 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*


        


More information about the llvm-commits mailing list