[llvm] e638a29 - [ConstantFold] Delay fetching pointer element type

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 22 06:51:42 PDT 2021


Author: Nikita Popov
Date: 2021-06-22T15:51:00+02:00
New Revision: e638a290f7d0bb85dbf81ba34eaaeef8c8d1b42d

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

LOG: [ConstantFold] Delay fetching pointer element type

Don't do this while stipping pointer casts, instead fetch it at
the end. This improves compatibility with opaque pointers for the
case where the base object is not opaque.

Added: 
    

Modified: 
    llvm/lib/Analysis/ConstantFolding.cpp
    llvm/test/Transforms/InstCombine/opaque-ptr.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index ceed375aef4c..1c6709c9fa1d 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -867,8 +867,7 @@ Constant *CastGEPIndices(Type *SrcElemTy, ArrayRef<Constant *> Ops,
 }
 
 /// Strip the pointer casts, but preserve the address space information.
-Constant *StripPtrCastKeepAS(Constant *Ptr, Type *&ElemTy,
-                             bool ForLoadOperand) {
+Constant *StripPtrCastKeepAS(Constant *Ptr, bool ForLoadOperand) {
   assert(Ptr->getType()->isPointerTy() && "Not a pointer type");
   auto *OldPtrTy = cast<PointerType>(Ptr->getType());
   Ptr = cast<Constant>(Ptr->stripPointerCasts());
@@ -881,8 +880,6 @@ Constant *StripPtrCastKeepAS(Constant *Ptr, Type *&ElemTy,
 
   auto *NewPtrTy = cast<PointerType>(Ptr->getType());
 
-  ElemTy = NewPtrTy->getPointerElementType();
-
   // Preserve the address space number of the pointer.
   if (NewPtrTy->getAddressSpace() != OldPtrTy->getAddressSpace()) {
     Ptr = ConstantExpr::getPointerCast(
@@ -942,7 +939,7 @@ Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP,
             DL.getIndexedOffsetInType(
                 SrcElemTy,
                 makeArrayRef((Value * const *)Ops.data() + 1, Ops.size() - 1)));
-  Ptr = StripPtrCastKeepAS(Ptr, SrcElemTy, ForLoadOperand);
+  Ptr = StripPtrCastKeepAS(Ptr, ForLoadOperand);
 
   // If this is a GEP of a GEP, fold it all into a single GEP.
   while (auto *GEP = dyn_cast<GEPOperator>(Ptr)) {
@@ -964,7 +961,7 @@ Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP,
     Ptr = cast<Constant>(GEP->getOperand(0));
     SrcElemTy = GEP->getSourceElementType();
     Offset += APInt(BitWidth, DL.getIndexedOffsetInType(SrcElemTy, NestedOps));
-    Ptr = StripPtrCastKeepAS(Ptr, SrcElemTy, ForLoadOperand);
+    Ptr = StripPtrCastKeepAS(Ptr, ForLoadOperand);
   }
 
   // If the base value for this address is a literal integer value, fold the
@@ -988,8 +985,9 @@ Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP,
   // we eliminate over-indexing of the notional static type array bounds.
   // This makes it easy to determine if the getelementptr is "inbounds".
   // Also, this helps GlobalOpt do SROA on GlobalVariables.
-  Type *Ty = PTy;
   SmallVector<Constant *, 32> NewIdxs;
+  Type *Ty = PTy;
+  SrcElemTy = PTy->getElementType();
 
   do {
     if (!Ty->isStructTy()) {
@@ -1074,7 +1072,7 @@ Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP,
 
   // If we ended up indexing a member with a type that doesn't match
   // the type of what the original indices indexed, add a cast.
-  if (Ty != ResElemTy)
+  if (C->getType() != ResTy)
     C = FoldBitCast(C, ResTy, DL);
 
   return C;

diff  --git a/llvm/test/Transforms/InstCombine/opaque-ptr.ll b/llvm/test/Transforms/InstCombine/opaque-ptr.ll
index cd8e3c273456..079f731a454a 100644
--- a/llvm/test/Transforms/InstCombine/opaque-ptr.ll
+++ b/llvm/test/Transforms/InstCombine/opaque-ptr.ll
@@ -49,3 +49,17 @@ define ptr @bitcast_typed_to_opaque_constexpr() {
 ;  %b = addrspacecast ptr addrspace(1) %a to i8*
 ;  ret i8* %b
 ;}
+
+define ptr @gep_constexpr_1(ptr %a) {
+; CHECK-LABEL: @gep_constexpr_1(
+; CHECK-NEXT:    ret ptr inttoptr (i64 6 to ptr)
+;
+  ret ptr getelementptr (i16, ptr null, i32 3)
+}
+
+define ptr @gep_constexpr_2(ptr %a) {
+; CHECK-LABEL: @gep_constexpr_2(
+; CHECK-NEXT:    ret ptr bitcast (i8* getelementptr (i8, i8* @g, i64 3) to ptr)
+;
+  ret ptr getelementptr (i8, ptr bitcast (i8* @g to ptr), i32 3)
+}


        


More information about the llvm-commits mailing list