[llvm] d9fe96f - [OpaquePtr] Support opaque constant expression GEP

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 21 11:09:18 PDT 2021


Author: Nikita Popov
Date: 2021-06-21T20:06:25+02:00
New Revision: d9fe96fe264e72c0a5c58cdd40b4efa14d18f475

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

LOG: [OpaquePtr] Support opaque constant expression GEP

Adjust assertions to use isOpaqueOrPointeeTypeMatches() and make
it return an opaque pointer result for an opaque base pointer. We
also need to enumerate the element type, as it is no longer
implicitly enumerated through the pointer type.

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

Added: 
    

Modified: 
    llvm/lib/AsmParser/LLParser.cpp
    llvm/lib/Bitcode/Reader/BitcodeReader.cpp
    llvm/lib/Bitcode/Writer/ValueEnumerator.cpp
    llvm/lib/IR/Constants.cpp
    llvm/test/Assembler/opaque-ptr.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index 1381ca6b61b42..c188766e0077a 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -3849,7 +3849,7 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS) {
 
       Type *BaseType = Elts[0]->getType();
       auto *BasePointerType = cast<PointerType>(BaseType->getScalarType());
-      if (Ty != BasePointerType->getElementType()) {
+      if (!BasePointerType->isOpaqueOrPointeeTypeMatches(Ty)) {
         return error(
             ExplicitTypeLoc,
             typeComparisonErrorMessage(

diff  --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index fef6b917b32b6..e002019cfcaeb 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -2663,11 +2663,10 @@ Error BitcodeReader::parseConstants() {
       if (Elts.size() < 1)
         return error("Invalid gep with no operands");
 
-      Type *ImplicitPointeeType =
-          cast<PointerType>(Elt0FullTy->getScalarType())->getElementType();
+      PointerType *OrigPtrTy = cast<PointerType>(Elt0FullTy->getScalarType());
       if (!PointeeType)
-        PointeeType = ImplicitPointeeType;
-      else if (PointeeType != ImplicitPointeeType)
+        PointeeType = OrigPtrTy->getElementType();
+      else if (!OrigPtrTy->isOpaqueOrPointeeTypeMatches(PointeeType))
         return error("Explicit gep operator type does not match pointee type "
                      "of pointer operand");
 

diff  --git a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp
index abfdcd67524e8..42d6abe8e69f8 100644
--- a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp
+++ b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp
@@ -28,6 +28,7 @@
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/Metadata.h"
 #include "llvm/IR/Module.h"
+#include "llvm/IR/Operator.h"
 #include "llvm/IR/Type.h"
 #include "llvm/IR/Use.h"
 #include "llvm/IR/User.h"
@@ -1006,9 +1007,12 @@ void ValueEnumerator::EnumerateOperandType(const Value *V) {
 
     EnumerateOperandType(Op);
   }
-  if (auto *CE = dyn_cast<ConstantExpr>(C))
+  if (auto *CE = dyn_cast<ConstantExpr>(C)) {
     if (CE->getOpcode() == Instruction::ShuffleVector)
       EnumerateOperandType(CE->getShuffleMaskForBitcode());
+    if (CE->getOpcode() == Instruction::GetElementPtr)
+      EnumerateType(cast<GEPOperator>(CE)->getSourceElementType());
+  }
 }
 
 void ValueEnumerator::EnumerateAttributes(AttributeList PAL) {

diff  --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp
index 147e96cf16d2a..2823a1eab4362 100644
--- a/llvm/lib/IR/Constants.cpp
+++ b/llvm/lib/IR/Constants.cpp
@@ -2425,11 +2425,11 @@ Constant *ConstantExpr::getGetElementPtr(Type *Ty, Constant *C,
                                          ArrayRef<Value *> Idxs, bool InBounds,
                                          Optional<unsigned> InRangeIndex,
                                          Type *OnlyIfReducedTy) {
+  PointerType *OrigPtrTy = cast<PointerType>(C->getType()->getScalarType());
   if (!Ty)
-    Ty = cast<PointerType>(C->getType()->getScalarType())->getElementType();
+    Ty = OrigPtrTy->getElementType();
   else
-    assert(Ty ==
-           cast<PointerType>(C->getType()->getScalarType())->getElementType());
+    assert(OrigPtrTy->isOpaqueOrPointeeTypeMatches(Ty));
 
   if (Constant *FC =
           ConstantFoldGetElementPtr(Ty, C, InBounds, InRangeIndex, Idxs))
@@ -2438,8 +2438,10 @@ Constant *ConstantExpr::getGetElementPtr(Type *Ty, Constant *C,
   // Get the result type of the getelementptr!
   Type *DestTy = GetElementPtrInst::getIndexedType(Ty, Idxs);
   assert(DestTy && "GEP indices invalid!");
-  unsigned AS = C->getType()->getPointerAddressSpace();
-  Type *ReqTy = DestTy->getPointerTo(AS);
+  unsigned AS = OrigPtrTy->getAddressSpace();
+  Type *ReqTy = OrigPtrTy->isOpaque()
+      ? PointerType::get(OrigPtrTy->getContext(), AS)
+      : DestTy->getPointerTo(AS);
 
   auto EltCount = ElementCount::getFixed(0);
   if (VectorType *VecTy = dyn_cast<VectorType>(C->getType()))

diff  --git a/llvm/test/Assembler/opaque-ptr.ll b/llvm/test/Assembler/opaque-ptr.ll
index 3a71da2f3537c..2e964afa93e99 100644
--- a/llvm/test/Assembler/opaque-ptr.ll
+++ b/llvm/test/Assembler/opaque-ptr.ll
@@ -65,6 +65,24 @@ define <2 x ptr> @gep_vec2(<2 x ptr> %a) {
   ret <2 x ptr> %res
 }
 
+; CHECK: define ptr @gep_constexpr(ptr %a)
+; CHECK:     ret ptr getelementptr (i16, ptr null, i32 3)
+define ptr @gep_constexpr(ptr %a) {
+  ret ptr getelementptr (i16, ptr null, i32 3)
+}
+
+; CHECK: define <2 x ptr> @gep_constexpr_vec1(ptr %a)
+; CHECK:     ret <2 x ptr> getelementptr (i16, ptr null, <2 x i32> <i32 3, i32 4>)
+define <2 x ptr> @gep_constexpr_vec1(ptr %a) {
+  ret <2 x ptr> getelementptr (i16, ptr null, <2 x i32> <i32 3, i32 4>)
+}
+
+; CHECK: define <2 x ptr> @gep_constexpr_vec2(<2 x ptr> %a)
+; CHECK:     ret <2 x ptr> getelementptr (i16, <2 x ptr> zeroinitializer, <2 x i32> <i32 3, i32 3>)
+define <2 x ptr> @gep_constexpr_vec2(<2 x ptr> %a) {
+  ret <2 x ptr> getelementptr (i16, <2 x ptr> zeroinitializer, i32 3)
+}
+
 ; CHECK: define void @cmpxchg(ptr %p, i32 %a, i32 %b)
 ; CHECK:     %val_success = cmpxchg ptr %p, i32 %a, i32 %b acq_rel monotonic
 ; CHECK:     ret void


        


More information about the llvm-commits mailing list