[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