[llvm] [AMDGPU] Fix in-memory p7 layout in LowerBufferFatPointers (PR #218973)

via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 26 09:49:46 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-amdgpu

Author: Arseniy Obolenskiy (aobolensk)

<details>
<summary>Changes</summary>

i160 has a smaller alloc size and weaker alignment than ptr addrspace(7), so rewriting aggregate types in place moved field offsets that GEPs already baked in

---

Patch is 29.25 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/218973.diff


4 Files Affected:

- (modified) llvm/lib/Target/AMDGPU/AMDGPULowerBufferFatPointers.cpp (+118-80) 
- (modified) llvm/test/CodeGen/AMDGPU/lower-buffer-fat-pointers-constants.ll (+1-1) 
- (modified) llvm/test/CodeGen/AMDGPU/lower-buffer-fat-pointers-p7-in-memory.ll (+165-38) 
- (modified) llvm/test/CodeGen/AMDGPU/lower-buffer-fat-pointers-unoptimized-debug-data.ll (+2-2) 


``````````diff
diff --git a/llvm/lib/Target/AMDGPU/AMDGPULowerBufferFatPointers.cpp b/llvm/lib/Target/AMDGPU/AMDGPULowerBufferFatPointers.cpp
index 39653fc985e5c..f9780ff5ae78f 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPULowerBufferFatPointers.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPULowerBufferFatPointers.cpp
@@ -51,10 +51,10 @@
 // including aggregates containing such pointers, to ones that use `i160`. This
 // is handled by `StoreFatPtrsAsIntsAndExpandMemcpyVisitor` , which visits
 // loads, stores, and allocas and, if the loaded or stored type contains `ptr
-// addrspace(7)`, rewrites that type to one where the p7s are replaced by i160s,
-// copying other parts of aggregates as needed. In the case of a store, each
-// pointer is `ptrtoint`d to i160 before storing, and load integers are
-// `inttoptr`d back. This same transformation is applied to vectors of pointers.
+// addrspace(7)`, rewrites it to use i160, `ptrtoint`ing before stores and
+// `inttoptr`ing after loads. Vectors of pointers work the same way. Since i160
+// and p7 differ in size and alignment, aggregates are split into one access per
+// leaf, and allocas and GEPs use byte offsets and sizes from the original type.
 //
 // Such a transformation allows the later phases of the pass to not need
 // to handle buffer fat pointers moving to and from memory, where we load
@@ -437,23 +437,27 @@ class StoreFatPtrsAsIntsAndExpandMemcpyVisitor
 
   IRBuilder<InstSimplifyFolder> IRB;
 
+  const DataLayout &DL;
+
   // Used for memcpy() lowering.
   const TargetTransformInfo *TTI;
   ScalarEvolution *SE;
 
-  // Convert all the buffer fat pointers within the input value to inttegers
-  // so that it can be stored in memory.
-  Value *fatPtrsToInts(Value *V, Type *From, Type *To, const Twine &Name);
-  // Convert all the i160s that need to be buffer fat pointers (as specified)
-  // by the To type) into those pointers to preserve the semantics of the rest
-  // of the program.
-  Value *intsToFatPtrs(Value *V, Type *From, Type *To, const Twine &Name);
+  Value *gepToOffset(Value *Ptr, uint64_t Off);
+  // Visits each maximal subtree of `Ty` that is fat-ptr-free or is itself a
+  // [vector of] fat pointer(s), at its offset in `Ty`'s original layout.
+  void forEachAggLeaf(
+      Type *Ty, SmallVectorImpl<unsigned> &AggIdxs, uint64_t Off,
+      const Twine &Name,
+      function_ref<void(Type *LeafTy, Type *IntLeafTy, ArrayRef<unsigned> Idxs,
+                        uint64_t Off, const Twine &Name)>
+          Visit);
 
 public:
   StoreFatPtrsAsIntsAndExpandMemcpyVisitor(BufferFatPtrToIntTypeMap *TypeMap,
                                            const DataLayout &DL,
                                            LLVMContext &Ctx)
-      : TypeMap(TypeMap), IRB(Ctx, InstSimplifyFolder(DL)) {}
+      : TypeMap(TypeMap), IRB(Ctx, InstSimplifyFolder(DL)), DL(DL) {}
   bool processFunction(Function &F, const TargetTransformInfo *TTI,
                        ScalarEvolution *SE);
 
@@ -470,68 +474,45 @@ class StoreFatPtrsAsIntsAndExpandMemcpyVisitor
 };
 } // namespace
 
-Value *StoreFatPtrsAsIntsAndExpandMemcpyVisitor::fatPtrsToInts(
-    Value *V, Type *From, Type *To, const Twine &Name) {
-  if (From == To)
-    return V;
-  if (isBufferFatPtrOrVector(From))
-    return IRB.CreatePtrToInt(V, To, Name + ".int");
-  if (From->getNumContainedTypes() == 0)
-    return V;
-  // Structs, arrays, and other compound types.
-  Value *Ret = PoisonValue::get(To);
-  if (auto *AT = dyn_cast<ArrayType>(From)) {
-    Type *FromPart = AT->getArrayElementType();
-    Type *ToPart = cast<ArrayType>(To)->getElementType();
-    for (uint64_t I = 0, E = AT->getArrayNumElements(); I < E; ++I) {
-      Value *Field = IRB.CreateExtractValue(V, I);
-      Value *NewField =
-          fatPtrsToInts(Field, FromPart, ToPart, Name + "." + Twine(I));
-      Ret = IRB.CreateInsertValue(Ret, NewField, I);
-    }
-  } else {
-    for (auto [Idx, FromPart, ToPart] :
-         enumerate(From->subtypes(), To->subtypes())) {
-      Value *Field = IRB.CreateExtractValue(V, Idx);
-      Value *NewField =
-          fatPtrsToInts(Field, FromPart, ToPart, Name + "." + Twine(Idx));
-      Ret = IRB.CreateInsertValue(Ret, NewField, Idx);
-    }
+Value *StoreFatPtrsAsIntsAndExpandMemcpyVisitor::gepToOffset(Value *Ptr,
+                                                             uint64_t Off) {
+  // The InstSimplifyFolder gives back `Ptr` itself when `Off` is 0.
+  return IRB.CreatePtrAdd(
+      Ptr, ConstantInt::get(DL.getIndexType(Ptr->getType()), Off),
+      Ptr->getName() + ".off." + Twine(Off), GEPNoWrapFlags::noUnsignedWrap());
+}
+
+void StoreFatPtrsAsIntsAndExpandMemcpyVisitor::forEachAggLeaf(
+    Type *Ty, SmallVectorImpl<unsigned> &AggIdxs, uint64_t Off,
+    const Twine &Name,
+    function_ref<void(Type *LeafTy, Type *IntLeafTy, ArrayRef<unsigned> Idxs,
+                      uint64_t Off, const Twine &Name)>
+        Visit) {
+  Type *IntTy = TypeMap->remapType(Ty);
+  if (isBufferFatPtrOrVector(Ty) || Ty == IntTy) {
+    // Zero-sized leaves ({} or [0 x T]) access no bytes; skip them.
+    if (DL.getTypeStoreSize(Ty) != 0)
+      Visit(Ty, IntTy, AggIdxs, Off, Name);
+    return;
   }
-  return Ret;
-}
-
-Value *StoreFatPtrsAsIntsAndExpandMemcpyVisitor::intsToFatPtrs(
-    Value *V, Type *From, Type *To, const Twine &Name) {
-  if (From == To)
-    return V;
-  if (isBufferFatPtrOrVector(To)) {
-    Value *Cast = IRB.CreateIntToPtr(V, To, Name + ".ptr");
-    return Cast;
-  }
-  if (From->getNumContainedTypes() == 0)
-    return V;
-  // Structs, arrays, and other compound types.
-  Value *Ret = PoisonValue::get(To);
-  if (auto *AT = dyn_cast<ArrayType>(From)) {
-    Type *FromPart = AT->getArrayElementType();
-    Type *ToPart = cast<ArrayType>(To)->getElementType();
-    for (uint64_t I = 0, E = AT->getArrayNumElements(); I < E; ++I) {
-      Value *Field = IRB.CreateExtractValue(V, I);
-      Value *NewField =
-          intsToFatPtrs(Field, FromPart, ToPart, Name + "." + Twine(I));
-      Ret = IRB.CreateInsertValue(Ret, NewField, I);
-    }
-  } else {
-    for (auto [Idx, FromPart, ToPart] :
-         enumerate(From->subtypes(), To->subtypes())) {
-      Value *Field = IRB.CreateExtractValue(V, Idx);
-      Value *NewField =
-          intsToFatPtrs(Field, FromPart, ToPart, Name + "." + Twine(Idx));
-      Ret = IRB.CreateInsertValue(Ret, NewField, Idx);
-    }
+  auto Recurse = [&](unsigned I, Type *ElemTy, uint64_t ElemOff) {
+    AggIdxs.push_back(I);
+    forEachAggLeaf(ElemTy, AggIdxs, Off + ElemOff, Name + "." + Twine(I),
+                   Visit);
+    AggIdxs.pop_back();
+  };
+  if (auto *ST = dyn_cast<StructType>(Ty)) {
+    const StructLayout *Layout = DL.getStructLayout(ST);
+    for (auto [I, ElemTy, ElemOff] :
+         enumerate(ST->elements(), Layout->getMemberOffsets()))
+      Recurse(I, ElemTy, ElemOff.getFixedValue());
+    return;
   }
-  return Ret;
+  auto *AT = cast<ArrayType>(Ty);
+  Type *ElemTy = AT->getElementType();
+  uint64_t Stride = DL.getTypeAllocSize(ElemTy).getFixedValue();
+  for (unsigned I : seq<unsigned>(AT->getNumElements()))
+    Recurse(I, ElemTy, I * Stride);
 }
 
 bool StoreFatPtrsAsIntsAndExpandMemcpyVisitor::processFunction(
@@ -561,6 +542,11 @@ bool StoreFatPtrsAsIntsAndExpandMemcpyVisitor::visitAllocaInst(AllocaInst &I) {
   Type *NewTy = TypeMap->remapType(Ty);
   if (Ty == NewTy)
     return false;
+  // i160 is smaller than ptr addrspace(7) (24 bytes vs. 32); fall back to a
+  // byte array of the original size so sizes computed from Ty stay in bounds.
+  TypeSize AllocSize = DL.getTypeAllocSize(Ty);
+  if (AllocSize.isFixed() && DL.getTypeAllocSize(NewTy) != AllocSize)
+    NewTy = ArrayType::get(IRB.getInt8Ty(), AllocSize.getFixedValue());
   I.setAllocatedType(NewTy);
   return true;
 }
@@ -568,13 +554,16 @@ bool StoreFatPtrsAsIntsAndExpandMemcpyVisitor::visitAllocaInst(AllocaInst &I) {
 bool StoreFatPtrsAsIntsAndExpandMemcpyVisitor::visitGetElementPtrInst(
     GetElementPtrInst &I) {
   Type *Ty = I.getSourceElementType();
-  Type *NewTy = TypeMap->remapType(Ty);
-  if (Ty == NewTy)
+  if (Ty == TypeMap->remapType(Ty))
     return false;
-  // We'll be rewriting the type `ptr addrspace(7)` out of existence soon, so
-  // make sure GEPs don't have different semantics with the new type.
-  I.setSourceElementType(NewTy);
-  I.setResultElementType(TypeMap->remapType(I.getResultElementType()));
+  // Lower to a byte offset now, before remapping changes p7's layout (see file
+  // header).
+  IRB.SetInsertPoint(&I);
+  Value *Off = emitGEPOffset(&IRB, DL, &I);
+  Value *NewGEP = IRB.CreatePtrAdd(I.getPointerOperand(), Off, I.getName(),
+                                   I.getNoWrapFlags());
+  I.replaceAllUsesWith(NewGEP);
+  I.eraseFromParent();
   return true;
 }
 
@@ -585,12 +574,37 @@ bool StoreFatPtrsAsIntsAndExpandMemcpyVisitor::visitLoadInst(LoadInst &LI) {
     return false;
 
   IRB.SetInsertPoint(&LI);
+  if (!isBufferFatPtrOrVector(Ty)) {
+    // i160 has the same 20-byte store size as p7, so loading each leaf at
+    // its original-layout offset accesses the same bytes as the unlowered load.
+    Value *Agg = PoisonValue::get(Ty);
+    AAMDNodes AATags = LI.getAAMetadata();
+    SmallVector<unsigned> AggIdxs;
+    forEachAggLeaf(
+        Ty, AggIdxs, 0, LI.getName(),
+        [&](Type *LeafTy, Type *IntLeafTy, ArrayRef<unsigned> Idxs,
+            uint64_t Off, const Twine &Name) {
+          Value *Ptr = gepToOffset(LI.getPointerOperand(), Off);
+          LoadInst *NewLI = IRB.CreateAlignedLoad(
+              IntLeafTy, Ptr, commonAlignment(LI.getAlign(), Off), Name);
+          NewLI->setVolatile(LI.isVolatile());
+          copyMetadataForLoad(*NewLI, LI);
+          NewLI->setAAMetadata(AATags.adjustForAccess(Off, IntLeafTy, DL));
+          Value *V = NewLI;
+          if (LeafTy != IntLeafTy)
+            V = IRB.CreateIntToPtr(NewLI, LeafTy, Name + ".ptr");
+          Agg = IRB.CreateInsertValue(Agg, V, Idxs, Name + ".agg");
+        });
+    LI.replaceAllUsesWith(Agg);
+    LI.eraseFromParent();
+    return true;
+  }
   auto *NLI = cast<LoadInst>(LI.clone());
   NLI->mutateType(IntTy);
   NLI = IRB.Insert(NLI);
   NLI->takeName(&LI);
 
-  Value *CastBack = intsToFatPtrs(NLI, IntTy, Ty, NLI->getName());
+  Value *CastBack = IRB.CreateIntToPtr(NLI, Ty, NLI->getName() + ".ptr");
   LI.replaceAllUsesWith(CastBack);
   LI.eraseFromParent();
   return true;
@@ -604,7 +618,31 @@ bool StoreFatPtrsAsIntsAndExpandMemcpyVisitor::visitStoreInst(StoreInst &SI) {
     return false;
 
   IRB.SetInsertPoint(&SI);
-  Value *IntV = fatPtrsToInts(V, Ty, IntTy, V->getName());
+  if (!isBufferFatPtrOrVector(Ty)) {
+    // Store each leaf at its byte offset in the original layout; see
+    // visitLoadInst.
+    AAMDNodes AATags = SI.getAAMetadata();
+    SmallVector<unsigned> AggIdxs;
+    forEachAggLeaf(
+        Ty, AggIdxs, 0, V->getName(),
+        [&](Type *LeafTy, Type *IntLeafTy, ArrayRef<unsigned> Idxs,
+            uint64_t Off, const Twine &Name) {
+          Value *Leaf = IRB.CreateExtractValue(V, Idxs, Name);
+          if (LeafTy != IntLeafTy)
+            Leaf = IRB.CreatePtrToInt(Leaf, IntLeafTy, Name + ".int");
+          auto *NewSI = cast<StoreInst>(SI.clone());
+          NewSI->setAlignment(commonAlignment(SI.getAlign(), Off));
+          NewSI->setOperand(0, Leaf);
+          NewSI->setOperand(1, gepToOffset(SI.getPointerOperand(), Off));
+          // Each leaf covers only part of the original assignment.
+          NewSI->setMetadata(LLVMContext::MD_DIAssignID, nullptr);
+          IRB.Insert(NewSI);
+          NewSI->setAAMetadata(AATags.adjustForAccess(Off, IntLeafTy, DL));
+        });
+    SI.eraseFromParent();
+    return true;
+  }
+  Value *IntV = IRB.CreatePtrToInt(V, IntTy, V->getName() + ".int");
   for (auto *Dbg : at::getDVRAssignmentMarkers(&SI))
     Dbg->setRawLocation(ValueAsMetadata::get(IntV));
 
diff --git a/llvm/test/CodeGen/AMDGPU/lower-buffer-fat-pointers-constants.ll b/llvm/test/CodeGen/AMDGPU/lower-buffer-fat-pointers-constants.ll
index e471178394303..970535c96745f 100644
--- a/llvm/test/CodeGen/AMDGPU/lower-buffer-fat-pointers-constants.ll
+++ b/llvm/test/CodeGen/AMDGPU/lower-buffer-fat-pointers-constants.ll
@@ -117,7 +117,7 @@ define ptr @gep_of_p7_struct() {
 
 define ptr addrspace(7) @gep_p7_from_p7() {
 ; CHECK-LABEL: define { ptr addrspace(8), i32 } @gep_p7_from_p7() {
-; CHECK-NEXT:    ret { ptr addrspace(8), i32 } { ptr addrspace(8) @buf, i32 48 }
+; CHECK-NEXT:    ret { ptr addrspace(8), i32 } { ptr addrspace(8) @buf, i32 64 }
 ;
   ret ptr addrspace(7) getelementptr (ptr addrspace(7),
   ptr addrspace(7) addrspacecast (ptr addrspace(8) @buf to ptr addrspace(7)),
diff --git a/llvm/test/CodeGen/AMDGPU/lower-buffer-fat-pointers-p7-in-memory.ll b/llvm/test/CodeGen/AMDGPU/lower-buffer-fat-pointers-p7-in-memory.ll
index 071666e4a6d75..db259c60cc701 100644
--- a/llvm/test/CodeGen/AMDGPU/lower-buffer-fat-pointers-p7-in-memory.ll
+++ b/llvm/test/CodeGen/AMDGPU/lower-buffer-fat-pointers-p7-in-memory.ll
@@ -12,8 +12,8 @@ define void @scalar_copy(ptr %a, ptr %b) {
 ; CHECK-NEXT:    [[TMP2:%.*]] = trunc i160 [[TMP1]] to i128
 ; CHECK-NEXT:    [[X_PTR_RSRC:%.*]] = inttoptr i128 [[TMP2]] to ptr addrspace(8)
 ; CHECK-NEXT:    [[X_PTR_OFF:%.*]] = trunc i160 [[X]] to i32
-; CHECK-NEXT:    [[B1:%.*]] = getelementptr i160, ptr [[B]], i64 1
-; CHECK-NEXT:    store i160 [[X]], ptr [[B1]], align 32
+; CHECK-NEXT:    [[B11:%.*]] = getelementptr i8, ptr [[B]], i64 32
+; CHECK-NEXT:    store i160 [[X]], ptr [[B11]], align 32
 ; CHECK-NEXT:    ret void
 ;
   %x = load ptr addrspace(7), ptr %a
@@ -30,8 +30,8 @@ define void @vector_copy(ptr %a, ptr %b) {
 ; CHECK-NEXT:    [[TMP2:%.*]] = trunc <4 x i160> [[TMP1]] to <4 x i128>
 ; CHECK-NEXT:    [[X_PTR_RSRC:%.*]] = inttoptr <4 x i128> [[TMP2]] to <4 x ptr addrspace(8)>
 ; CHECK-NEXT:    [[X_PTR_OFF:%.*]] = trunc <4 x i160> [[X]] to <4 x i32>
-; CHECK-NEXT:    [[B1:%.*]] = getelementptr <4 x i160>, ptr [[B]], i64 2
-; CHECK-NEXT:    store <4 x i160> [[X]], ptr [[B1]], align 128
+; CHECK-NEXT:    [[B11:%.*]] = getelementptr i8, ptr [[B]], i64 256
+; CHECK-NEXT:    store <4 x i160> [[X]], ptr [[B11]], align 128
 ; CHECK-NEXT:    ret void
 ;
   %x = load <4 x ptr addrspace(7)>, ptr %a
@@ -43,15 +43,15 @@ define void @vector_copy(ptr %a, ptr %b) {
 define void @alloca(ptr %a, ptr %b) {
 ; CHECK-LABEL: define void @alloca
 ; CHECK-SAME: (ptr [[A:%.*]], ptr [[B:%.*]]) {
-; CHECK-NEXT:    [[ALLOCA:%.*]] = alloca [5 x i160], align 32, addrspace(5)
+; CHECK-NEXT:    [[ALLOCA:%.*]] = alloca [160 x i8], align 32, addrspace(5)
 ; CHECK-NEXT:    [[X:%.*]] = load i160, ptr [[A]], align 32
 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr i160 [[X]], 32
 ; CHECK-NEXT:    [[TMP2:%.*]] = trunc i160 [[TMP1]] to i128
 ; CHECK-NEXT:    [[X_PTR_RSRC:%.*]] = inttoptr i128 [[TMP2]] to ptr addrspace(8)
 ; CHECK-NEXT:    [[X_PTR_OFF:%.*]] = trunc i160 [[X]] to i32
-; CHECK-NEXT:    [[L:%.*]] = getelementptr i160, ptr addrspace(5) [[ALLOCA]], i32 1
-; CHECK-NEXT:    store i160 [[X]], ptr addrspace(5) [[L]], align 32
-; CHECK-NEXT:    [[Y:%.*]] = load i160, ptr addrspace(5) [[L]], align 32
+; CHECK-NEXT:    [[L1:%.*]] = getelementptr i8, ptr addrspace(5) [[ALLOCA]], i32 32
+; CHECK-NEXT:    store i160 [[X]], ptr addrspace(5) [[L1]], align 32
+; CHECK-NEXT:    [[Y:%.*]] = load i160, ptr addrspace(5) [[L1]], align 32
 ; CHECK-NEXT:    [[TMP3:%.*]] = lshr i160 [[Y]], 32
 ; CHECK-NEXT:    [[TMP4:%.*]] = trunc i160 [[TMP3]] to i128
 ; CHECK-NEXT:    [[Y_PTR_RSRC:%.*]] = inttoptr i128 [[TMP4]] to ptr addrspace(8)
@@ -71,36 +71,42 @@ define void @alloca(ptr %a, ptr %b) {
 define void @complex_copy(ptr %a, ptr %b) {
 ; CHECK-LABEL: define void @complex_copy
 ; CHECK-SAME: (ptr [[A:%.*]], ptr [[B:%.*]]) {
-; CHECK-NEXT:    [[X:%.*]] = load { [2 x i160], i32, i160 }, ptr [[A]], align 32
-; CHECK-NEXT:    [[TMP1:%.*]] = extractvalue { [2 x i160], i32, i160 } [[X]], 0
-; CHECK-NEXT:    [[TMP2:%.*]] = extractvalue [2 x i160] [[TMP1]], 0
-; CHECK-NEXT:    [[TMP3:%.*]] = lshr i160 [[TMP2]], 32
-; CHECK-NEXT:    [[TMP4:%.*]] = trunc i160 [[TMP3]] to i128
-; CHECK-NEXT:    [[X_0_0_PTR_RSRC:%.*]] = inttoptr i128 [[TMP4]] to ptr addrspace(8)
-; CHECK-NEXT:    [[X_0_0_PTR_OFF:%.*]] = trunc i160 [[TMP2]] to i32
-; CHECK-NEXT:    [[TMP5:%.*]] = insertvalue { ptr addrspace(8), i32 } poison, ptr addrspace(8) [[X_0_0_PTR_RSRC]], 0
-; CHECK-NEXT:    [[X_0_0_PTR:%.*]] = insertvalue { ptr addrspace(8), i32 } [[TMP5]], i32 [[X_0_0_PTR_OFF]], 1
-; CHECK-NEXT:    [[TMP6:%.*]] = insertvalue [2 x { ptr addrspace(8), i32 }] poison, { ptr addrspace(8), i32 } [[X_0_0_PTR]], 0
-; CHECK-NEXT:    [[TMP7:%.*]] = extractvalue [2 x i160] [[TMP1]], 1
-; CHECK-NEXT:    [[TMP8:%.*]] = lshr i160 [[TMP7]], 32
-; CHECK-NEXT:    [[TMP9:%.*]] = trunc i160 [[TMP8]] to i128
-; CHECK-NEXT:    [[X_0_1_PTR_RSRC:%.*]] = inttoptr i128 [[TMP9]] to ptr addrspace(8)
-; CHECK-NEXT:    [[X_0_1_PTR_OFF:%.*]] = trunc i160 [[TMP7]] to i32
-; CHECK-NEXT:    [[TMP10:%.*]] = insertvalue { ptr addrspace(8), i32 } poison, ptr addrspace(8) [[X_0_1_PTR_RSRC]], 0
-; CHECK-NEXT:    [[X_0_1_PTR:%.*]] = insertvalue { ptr addrspace(8), i32 } [[TMP10]], i32 [[X_0_1_PTR_OFF]], 1
-; CHECK-NEXT:    [[TMP11:%.*]] = insertvalue [2 x { ptr addrspace(8), i32 }] [[TMP6]], { ptr addrspace(8), i32 } [[X_0_1_PTR]], 1
-; CHECK-NEXT:    [[TMP12:%.*]] = insertvalue { [2 x { ptr addrspace(8), i32 }], i32, { ptr addrspace(8), i32 } } poison, [2 x { ptr addrspace(8), i32 }] [[TMP11]], 0
-; CHECK-NEXT:    [[TMP13:%.*]] = extractvalue { [2 x i160], i32, i160 } [[X]], 1
-; CHECK-NEXT:    [[TMP14:%.*]] = insertvalue { [2 x { ptr addrspace(8), i32 }], i32, { ptr addrspace(8), i32 } } [[TMP12]], i32 [[TMP13]], 1
-; CHECK-NEXT:    [[TMP15:%.*]] = extractvalue { [2 x i160], i32, i160 } [[X]], 2
-; CHECK-NEXT:    [[TMP16:%.*]] = lshr i160 [[TMP15]], 32
-; CHECK-NEXT:    [[TMP17:%.*]] = trunc i160 [[TMP16]] to i128
-; CHECK-NEXT:    [[X_2_PTR_RSRC:%.*]] = inttoptr i128 [[TMP17]] to ptr addrspace(8)
-; CHECK-NEXT:    [[X_2_PTR_OFF:%.*]] = trunc i160 [[TMP15]] to i32
-; CHECK-NEXT:    [[TMP18:%.*]] = insertvalue { ptr addrspace(8), i32 } poison, ptr addrspace(8) [[X_2_PTR_RSRC]], 0
-; CHECK-NEXT:    [[X_2_PTR:%.*]] = insertvalue { ptr addrspace(8), i32 } [[TMP18]], i32 [[X_2_PTR_OFF]], 1
-; CHECK-NEXT:    [[TMP19:%.*]] = insertvalue { [2 x { ptr addrspace(8), i32 }], i32, { ptr addrspace(8), i32 } } [[TMP14]], { ptr addrspace(8), i32 } [[X_2_PTR]], 2
-; CHECK-NEXT:    store { [2 x i160], i32, i160 } [[X]], ptr [[B]], align 32
+; CHECK-NEXT:    [[X_0_0:%.*]] = load i160, ptr [[A]], align 32
+; CHECK-NEXT:    [[TMP1:%.*]] = lshr i160 [[X_0_0]], 32
+; CHECK-NEXT:    [[TMP2:%.*]] = trunc i160 [[TMP1]] to i128
+; CHECK-NEXT:    [[X_0_0_PTR_RSRC:%.*]] = inttoptr i128 [[TMP2]] to ptr addrspace(8)
+; CHECK-NEXT:    [[X_0_0_PTR_OFF:%.*]] = trunc i160 [[X_0_0]] to i32
+; CHECK-NEXT:    [[TMP3:%.*]] = insertvalue { ptr addrspace(8), i32 } poison, ptr addrspace(8) [[X_0_0_PTR_RSRC]], 0
+; CHECK-NEXT:    [[X_0_0_PTR:%.*]] = insertvalue { ptr addrspace(8), i32 } [[TMP3]], i32 [[X_0_0_PTR_OFF]], 1
+; CHECK-NEXT:    [[X_0_0_AGG:%.*]] = insertvalue { [2 x { ptr addrspace(8), i32 }], i32, { ptr addrspace(8), i32 } } poison, { ptr addrspace(8), i32 } [[X_0_0_PTR]], 0, 0
+; CHECK-NEXT:    [[A_OFF_32:%.*]] = getelementptr nuw i8, ptr [[A]], i64 32
+; CHECK-NEXT:    [[X_0_1:%.*]] = load i160, ptr [[A_OFF_32]], align 32
+; CHECK-NEXT:    [[TMP4:%.*]] = lshr i160 [[X_0_1]], 32
+; CHECK-NEXT:    [[TMP5:%.*]] = trunc i160 [[TMP4]] to i128
+; CHECK-NEXT:    [[X_0_1_PTR_RSRC:%.*]] = inttoptr i128 [[TMP5]] to ptr addrspace(8)
+; CHECK-NEXT:    [[X_0_1_PTR_OFF:%.*]] = trunc i160 [[X_0_1]] to i32
+; CHECK-NEXT:    [[TMP6:%.*]] = insertvalue { ptr addrspace(8), i32 } poison, ptr addrspace(8) [[X_0_1_PTR_RSRC]], 0
+; CHECK-NEXT:    [[X_0_1_PTR:%.*]] = insertvalue { ptr addrspace(8), i32 } [[TMP6]], i32 [[X_0_1_PTR_OFF]], 1
+; CHECK-NEXT:    [[X_0_1_AGG:%.*]] = insertvalue { [2 x { ptr addrspace(8), i32 }], i32, { ptr addrspace(8), i32 } } [[X_0_0_AGG]], { ptr addrspace(8), i32 } [[X_0_1_PTR]], 0, 1
+; CHECK-NEXT:    [[A_OFF_64:%.*]] = getelementptr nuw i8, ptr [[A]], i64 64
+; CHECK-NEXT:    [[X_1:%.*]] = load i32, ptr [[A_OFF_64]], align 32
+; CHECK-NEXT:    [[X_1_AGG:%.*]] = insertvalue { [2 x { ptr addrspace(8), i32 }], i32, { ptr addrspace(8), i32 } } [[X_0_1_AGG]], i32 [[X_1]], 1
+; CHECK-NEXT:    [[A...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/218973


More information about the llvm-commits mailing list