[llvm] 58db5f6 - [ConstFold] Support opaque pointers in constexpr GEPs

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 7 11:50:37 PDT 2021


Author: Nikita Popov
Date: 2021-09-07T20:50:29+02:00
New Revision: 58db5f6e959419aaca20798835d75d3646b99293

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

LOG: [ConstFold] Support opaque pointers in constexpr GEPs

Support opaque pointers in SymbolicallyEvaluateGEP() by using the
value type of a GlobalValue base or falling back to i8 if there
isn't one. We don't unconditionally generate i8 GEPs here because
that would lose inrange attribues, and because some optimizations
on globals currently rely on GEP types (e.g. the globals SROA
mentioned in the comment).

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

Added: 
    llvm/test/Transforms/InstCombine/force-opaque-ptr.ll

Modified: 
    llvm/lib/Analysis/ConstantFolding.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index 2c2e6c32d001..6ea7dcfbb53f 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -987,7 +987,15 @@ Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP,
   // Also, this helps GlobalOpt do SROA on GlobalVariables.
   SmallVector<Constant *, 32> NewIdxs;
   Type *Ty = PTy;
-  SrcElemTy = PTy->getElementType();
+
+  // For GEPs of GlobalValues, use the value type even for opaque pointers.
+  // Otherwise use an i8 GEP.
+  if (auto *GV = dyn_cast<GlobalValue>(Ptr))
+    SrcElemTy = GV->getValueType();
+  else if (!PTy->isOpaque())
+    SrcElemTy = PTy->getElementType();
+  else
+    SrcElemTy = Type::getInt8Ty(Ptr->getContext());
 
   do {
     if (!Ty->isStructTy()) {
@@ -1067,7 +1075,7 @@ Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP,
   // Create a GEP.
   Constant *C = ConstantExpr::getGetElementPtr(SrcElemTy, Ptr, NewIdxs,
                                                InBounds, InRangeIndex);
-  assert(C->getType()->getPointerElementType() == Ty &&
+  assert(cast<PointerType>(C->getType())->isOpaqueOrPointeeTypeMatches(Ty) &&
          "Computed GetElementPtr has unexpected type!");
 
   // If we ended up indexing a member with a type that doesn't match

diff  --git a/llvm/test/Transforms/InstCombine/force-opaque-ptr.ll b/llvm/test/Transforms/InstCombine/force-opaque-ptr.ll
new file mode 100644
index 000000000000..d239ec7710bf
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/force-opaque-ptr.ll
@@ -0,0 +1,26 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -S -instcombine -force-opaque-pointers < %s | FileCheck %s
+
+ at g = global [16 x i16] zeroinitializer
+
+define ptr @gep_constexpr_gv_1() {
+; CHECK-LABEL: @gep_constexpr_gv_1(
+; CHECK-NEXT:    ret ptr getelementptr inbounds ([16 x i16], ptr @g, i64 0, i64 10)
+;
+  ret ptr getelementptr([16 x i16], ptr @g, i64 0, i64 10)
+}
+
+define ptr @gep_constexpr_gv_2() {
+; CHECK-LABEL: @gep_constexpr_gv_2(
+; CHECK-NEXT:    ret ptr getelementptr inbounds ([16 x i16], ptr @g, i64 0, i64 12)
+;
+  ret ptr getelementptr(i32, ptr getelementptr([16 x i16], ptr @g, i64 0, i64 10), i64 1)
+}
+
+; Silly expression to get an inttoptr that does not combine with the GEP.
+define ptr @gep_constexpr_inttoptr() {
+; CHECK-LABEL: @gep_constexpr_inttoptr(
+; CHECK-NEXT:    ret ptr getelementptr (i8, ptr inttoptr (i64 mul (i64 ptrtoint (ptr @g to i64), i64 2) to ptr), i64 20)
+;
+  ret ptr getelementptr([16 x i16], ptr inttoptr (i64 mul (i64 ptrtoint ([16 x i16]* @g to i64), i64 2) to ptr), i64 0, i64 10)
+}


        


More information about the llvm-commits mailing list