63
63
using namespace llvm ;
64
64
65
65
namespace {
66
+ Constant *SymbolicallyEvaluateGEP (const GEPOperator *GEP,
67
+ ArrayRef<Constant *> Ops,
68
+ const DataLayout &DL,
69
+ const TargetLibraryInfo *TLI,
70
+ bool ForLoadOperand);
66
71
67
72
// ===----------------------------------------------------------------------===//
68
73
// Constant Folding internal helper functions
@@ -690,6 +695,33 @@ Constant *llvm::ConstantFoldLoadFromConstPtr(Constant *C, Type *Ty,
690
695
GV->getInitializer (), CE, Ty, DL))
691
696
return V;
692
697
}
698
+ } else {
699
+ // Try to simplify GEP if the pointer operand wasn't a GlobalVariable.
700
+ // SymbolicallyEvaluateGEP() with `ForLoadOperand = true` can potentially
701
+ // simplify the GEP more than it normally would have been, but should only
702
+ // be used for const folding loads.
703
+ SmallVector<Constant *> Ops;
704
+ for (unsigned I = 0 , E = CE->getNumOperands (); I != E; ++I)
705
+ Ops.push_back (cast<Constant>(CE->getOperand (I)));
706
+ if (auto *Simplified = dyn_cast_or_null<ConstantExpr>(
707
+ SymbolicallyEvaluateGEP (cast<GEPOperator>(CE), Ops, DL, nullptr ,
708
+ /* ForLoadOperand*/ true ))) {
709
+ // If the symbolically evaluated GEP is another GEP, we can only const
710
+ // fold it if the resulting pointer operand is a GlobalValue. Otherwise
711
+ // there is nothing else to simplify since the GEP is already in the
712
+ // most simplified form.
713
+ if (auto *SimplifiedGEP = dyn_cast<GEPOperator>(Simplified)) {
714
+ if (auto *GV = dyn_cast<GlobalVariable>(Simplified->getOperand (0 ))) {
715
+ if (GV->isConstant () && GV->hasDefinitiveInitializer ()) {
716
+ if (Constant *V = ConstantFoldLoadThroughGEPConstantExpr (
717
+ GV->getInitializer (), Simplified, Ty, DL))
718
+ return V;
719
+ }
720
+ }
721
+ } else {
722
+ return ConstantFoldLoadFromConstPtr (Simplified, Ty, DL);
723
+ }
724
+ }
693
725
}
694
726
}
695
727
@@ -835,10 +867,18 @@ Constant *CastGEPIndices(Type *SrcElemTy, ArrayRef<Constant *> Ops,
835
867
}
836
868
837
869
// / Strip the pointer casts, but preserve the address space information.
838
- Constant *StripPtrCastKeepAS (Constant *Ptr, Type *&ElemTy) {
870
+ Constant *StripPtrCastKeepAS (Constant *Ptr, Type *&ElemTy,
871
+ bool ForLoadOperand) {
839
872
assert (Ptr->getType ()->isPointerTy () && " Not a pointer type" );
840
873
auto *OldPtrTy = cast<PointerType>(Ptr->getType ());
841
874
Ptr = cast<Constant>(Ptr->stripPointerCasts ());
875
+ if (ForLoadOperand) {
876
+ while (isa<GlobalAlias>(Ptr) && !cast<GlobalAlias>(Ptr)->isInterposable () &&
877
+ !cast<GlobalAlias>(Ptr)->getBaseObject ()->isInterposable ()) {
878
+ Ptr = cast<GlobalAlias>(Ptr)->getAliasee ();
879
+ }
880
+ }
881
+
842
882
auto *NewPtrTy = cast<PointerType>(Ptr->getType ());
843
883
844
884
ElemTy = NewPtrTy->getPointerElementType ();
@@ -855,7 +895,8 @@ Constant *StripPtrCastKeepAS(Constant *Ptr, Type *&ElemTy) {
855
895
Constant *SymbolicallyEvaluateGEP (const GEPOperator *GEP,
856
896
ArrayRef<Constant *> Ops,
857
897
const DataLayout &DL,
858
- const TargetLibraryInfo *TLI) {
898
+ const TargetLibraryInfo *TLI,
899
+ bool ForLoadOperand) {
859
900
const GEPOperator *InnermostGEP = GEP;
860
901
bool InBounds = GEP->isInBounds ();
861
902
@@ -903,7 +944,7 @@ Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP,
903
944
DL.getIndexedOffsetInType (
904
945
SrcElemTy,
905
946
makeArrayRef ((Value * const *)Ops.data () + 1 , Ops.size () - 1 )));
906
- Ptr = StripPtrCastKeepAS (Ptr, SrcElemTy);
947
+ Ptr = StripPtrCastKeepAS (Ptr, SrcElemTy, ForLoadOperand );
907
948
908
949
// If this is a GEP of a GEP, fold it all into a single GEP.
909
950
while (auto *GEP = dyn_cast<GEPOperator>(Ptr)) {
@@ -925,7 +966,7 @@ Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP,
925
966
Ptr = cast<Constant>(GEP->getOperand (0 ));
926
967
SrcElemTy = GEP->getSourceElementType ();
927
968
Offset += APInt (BitWidth, DL.getIndexedOffsetInType (SrcElemTy, NestedOps));
928
- Ptr = StripPtrCastKeepAS (Ptr, SrcElemTy);
969
+ Ptr = StripPtrCastKeepAS (Ptr, SrcElemTy, ForLoadOperand );
929
970
}
930
971
931
972
// If the base value for this address is a literal integer value, fold the
@@ -1062,7 +1103,8 @@ Constant *ConstantFoldInstOperandsImpl(const Value *InstOrCE, unsigned Opcode,
1062
1103
return ConstantFoldCastOperand (Opcode, Ops[0 ], DestTy, DL);
1063
1104
1064
1105
if (auto *GEP = dyn_cast<GEPOperator>(InstOrCE)) {
1065
- if (Constant *C = SymbolicallyEvaluateGEP (GEP, Ops, DL, TLI))
1106
+ if (Constant *C = SymbolicallyEvaluateGEP (GEP, Ops, DL, TLI,
1107
+ /* ForLoadOperand*/ false ))
1066
1108
return C;
1067
1109
1068
1110
return ConstantExpr::getGetElementPtr (GEP->getSourceElementType (), Ops[0 ],
0 commit comments