[PATCH] D99961: [SimplifyInst] Use correct type for GEPs with vector indices.

Florian Hahn via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 6 08:14:47 PDT 2021


fhahn created this revision.
fhahn added reviewers: nikic, spatel, lebedev.ri, arsenm.
Herald added a subscriber: hiraditya.
fhahn requested review of this revision.
Herald added a subscriber: wdng.
Herald added a project: LLVM.

The current code does not properly handle vector indices unless they are
the first index.

At the moment LangRef gives the impression that the vector index must be
the one and only index (https://llvm.org/docs/LangRef.html#getelementptr-instruction).

But vector indices can appear at any position and according to the
verifier there may be multiple vector indices. If that's the case, the
number of elements must match.

This patch updates SimplifyGEPInst to properly handle those additional
cases.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D99961

Files:
  llvm/lib/Analysis/InstructionSimplify.cpp
  llvm/test/Transforms/InstSimplify/gep.ll


Index: llvm/test/Transforms/InstSimplify/gep.ll
===================================================================
--- llvm/test/Transforms/InstSimplify/gep.ll
+++ llvm/test/Transforms/InstSimplify/gep.ll
@@ -315,3 +315,32 @@
   %gep = getelementptr inbounds i32, i32* %c1, i64 %ashr
   ret i32* %gep
 }
+
+define <8 x i32*> @gep_vector_index_op2_poison([144 x i32]* %ptr) {
+; CHECK-LABEL: @gep_vector_index_op2_poison(
+; CHECK-NEXT:    ret <8 x i32*> poison
+;
+  %res = getelementptr inbounds [144 x i32], [144 x i32]* %ptr, i64 0, <8 x i64> poison
+  ret <8 x i32*> %res
+}
+
+%t.1 = type { i32, [144 x i32] }
+
+define <8 x i32*> @gep_vector_index_op3_poison(%t.1* %ptr) {
+; CHECK-LABEL: @gep_vector_index_op3_poison(
+; CHECK-NEXT:    ret <8 x i32*> poison
+;
+  %res = getelementptr inbounds %t.1, %t.1* %ptr, i64 0, i32 1, <8 x i64> poison
+  ret <8 x i32*> %res
+}
+
+%t.2 = type { i32, i32 }
+%t.3 = type { i32, [144 x %t.2 ] }
+
+define <8 x i32*> @gep_vector_index_op3_poison_constant_index_afterwards(%t.3* %ptr) {
+; CHECK-LABEL: @gep_vector_index_op3_poison_constant_index_afterwards(
+; CHECK-NEXT:    ret <8 x i32*> poison
+;
+  %res = getelementptr inbounds %t.3, %t.3* %ptr, i64 0, i32 1, <8 x i64> poison, i32 1
+  ret <8 x i32*> %res
+}
Index: llvm/lib/Analysis/InstructionSimplify.cpp
===================================================================
--- llvm/lib/Analysis/InstructionSimplify.cpp
+++ llvm/lib/Analysis/InstructionSimplify.cpp
@@ -4319,10 +4319,14 @@
   // Compute the (pointer) type returned by the GEP instruction.
   Type *LastType = GetElementPtrInst::getIndexedType(SrcTy, Ops.slice(1));
   Type *GEPTy = PointerType::get(LastType, AS);
-  if (VectorType *VT = dyn_cast<VectorType>(Ops[0]->getType()))
-    GEPTy = VectorType::get(GEPTy, VT->getElementCount());
-  else if (VectorType *VT = dyn_cast<VectorType>(Ops[1]->getType()))
-    GEPTy = VectorType::get(GEPTy, VT->getElementCount());
+  for (Value *Op : Ops) {
+    // If one of the operands is a vector, the result type is a vector of
+    // pointers. All vector operands must have the same number of elements.
+    if (VectorType *VT = dyn_cast<VectorType>(Op->getType())) {
+      GEPTy = VectorType::get(GEPTy, VT->getElementCount());
+      break;
+    }
+  }
 
   // getelementptr poison, idx -> poison
   // getelementptr baseptr, poison -> poison


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D99961.335516.patch
Type: text/x-patch
Size: 2362 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210406/91cdb729/attachment.bin>


More information about the llvm-commits mailing list