[llvm] [DirectX] Limit GEP transformations to Arrays (PR #145758)

Farzon Lotfi via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 25 11:17:15 PDT 2025


https://github.com/farzonl created https://github.com/llvm/llvm-project/pull/145758

fixes #145408

Before we see the GEP we already have transformed Allocas that get passed the `isArrayOfVectors`.
The bug is because we are trying to transform a gep for struct of arrays when we should only be transforming arrays.

The problem with our `visitGetElementPtrInst` is that it was doing transformations for all allocas when it should be limiting it to the alloca of array cases. Technically we would have liked to make sure it was an array of vectors cases but by the time we see the GEP the type has been changed by replace all uses. There should not be a problem with looking at all Arrays since DXILDataScalarization does not change any indicies.

>From 2f817d1c9e7341d634931e3deb3f849ce67035da Mon Sep 17 00:00:00 2001
From: Farzon Lotfi <farzonlotfi at microsoft.com>
Date: Wed, 25 Jun 2025 14:07:49 -0400
Subject: [PATCH] [DirectX] Limit GEP transformations to Arrays fixes #145408

Before we see the GEP we already have transformed Allocas that
get passed the `isArrayOfVectors`.
The problem with our `visitGetElementPtrInst` is that it was
doing transformations for all allocas when it should be limiting it
to the array cases. Technically we would have liked to make
sure it was an array of vectors cases but by the time we see
the GEP the type has been changed by replace all uses.
There should not be a problem with looking at all Arrays
since DXILDataScalarization does not change any indicies.
---
 .../Target/DirectX/DXILDataScalarization.cpp    |  5 ++---
 .../DirectX/issue-145408-gep-struct-fix.ll      | 17 +++++++++++++++++
 2 files changed, 19 insertions(+), 3 deletions(-)
 create mode 100644 llvm/test/CodeGen/DirectX/issue-145408-gep-struct-fix.ll

diff --git a/llvm/lib/Target/DirectX/DXILDataScalarization.cpp b/llvm/lib/Target/DirectX/DXILDataScalarization.cpp
index 0a9b2bb99f7eb..71eb1349314ea 100644
--- a/llvm/lib/Target/DirectX/DXILDataScalarization.cpp
+++ b/llvm/lib/Target/DirectX/DXILDataScalarization.cpp
@@ -308,9 +308,8 @@ bool DataScalarizerVisitor::visitGetElementPtrInst(GetElementPtrInst &GEPI) {
     NeedsTransform = true;
   } else if (AllocaInst *Alloca = dyn_cast<AllocaInst>(PtrOperand)) {
     Type *AllocatedType = Alloca->getAllocatedType();
-    // OrigGEPType might just be a pointer lets make sure
-    // to add the allocated type so we have a size
-    if (AllocatedType != OrigGEPType) {
+    // Only transform if the allocated type is an array
+    if (AllocatedType != OrigGEPType && isa<ArrayType>(AllocatedType)) {
       NewGEPType = AllocatedType;
       NeedsTransform = true;
     }
diff --git a/llvm/test/CodeGen/DirectX/issue-145408-gep-struct-fix.ll b/llvm/test/CodeGen/DirectX/issue-145408-gep-struct-fix.ll
new file mode 100644
index 0000000000000..40d222cdf2f8f
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/issue-145408-gep-struct-fix.ll
@@ -0,0 +1,17 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -S -dxil-data-scalarization -mtriple=dxil-pc-shadermodel6.3-library %s | FileCheck %s
+
+%struct.RawStruct8D = type { [8 x i32] }
+
+define void @test_no_transform_of_struct()  {
+; CHECK-LABEL: define void @test_no_transform_of_struct() {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    [[OUTPUTSIZESLOCAL_I:%.*]] = alloca [[STRUCT_RAWSTRUCT8D:%.*]], align 4
+; CHECK-NEXT:    [[ARRAYINIT_ELEMENT13_I76:%.*]] = getelementptr inbounds nuw [1 x %struct.RawStruct8D], ptr [[OUTPUTSIZESLOCAL_I]], i32 0, i32 0
+; CHECK-NEXT:    ret void
+;
+entry:
+  %outputSizesLocal.i = alloca %struct.RawStruct8D, align 4
+  %arrayinit.element13.i76 = getelementptr inbounds nuw [1 x %struct.RawStruct8D], ptr %outputSizesLocal.i, i32 0, i32 0
+  ret void
+}



More information about the llvm-commits mailing list