[llvm] [InstCombine] Prevent i8 canonicalize for SPIR-V (PR #147527)

via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 8 06:58:21 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-transforms

Author: Nathan Gauër (Keenuts)

<details>
<summary>Changes</summary>

The GEP return type is usually not very important: the load/store using the pointer will give meaning to the pointer. This however is not true for SPIR-V: our GEP equivalent (OpAccessChain) requires the return value to match the dereferenced struct/aggregate type.

For most cases, we can fixup this later in the backend, but the canonicalization makes type scavenging messier.

This commit conditionally disable this for the SPIR-V target to help determine the correct pointer type.

Related to #<!-- -->145002

---
Full diff: https://github.com/llvm/llvm-project/pull/147527.diff


2 Files Affected:

- (modified) llvm/lib/Transforms/InstCombine/InstructionCombining.cpp (+3-2) 
- (added) llvm/test/Transforms/InstCombine/canonicalize-spirv.ll (+23) 


``````````diff
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index 91a1b61ddc483..153ce002f10a4 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -3145,7 +3145,8 @@ Instruction *InstCombinerImpl::visitGetElementPtrInst(GetElementPtrInst &GEP) {
     return &GEP;
 
   // Canonicalize constant GEPs to i8 type.
-  if (!GEPEltType->isIntegerTy(8) && GEP.hasAllConstantIndices()) {
+  bool isSPIRV = GEP.getModule()->getTargetTriple().isSPIRV();
+  if (!isSPIRV && !GEPEltType->isIntegerTy(8) && GEP.hasAllConstantIndices()) {
     APInt Offset(DL.getIndexTypeSizeInBits(GEPType), 0);
     if (GEP.accumulateConstantOffset(DL, Offset))
       return replaceInstUsesWith(
@@ -3153,7 +3154,7 @@ Instruction *InstCombinerImpl::visitGetElementPtrInst(GetElementPtrInst &GEP) {
                                     GEP.getNoWrapFlags()));
   }
 
-  if (shouldCanonicalizeGEPToPtrAdd(GEP)) {
+  if (!isSPIRV && shouldCanonicalizeGEPToPtrAdd(GEP)) {
     Value *Offset = EmitGEPOffset(cast<GEPOperator>(&GEP));
     Value *NewGEP =
         Builder.CreatePtrAdd(PtrOp, Offset, "", GEP.getNoWrapFlags());
diff --git a/llvm/test/Transforms/InstCombine/canonicalize-spirv.ll b/llvm/test/Transforms/InstCombine/canonicalize-spirv.ll
new file mode 100644
index 0000000000000..953063c7d79d6
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/canonicalize-spirv.ll
@@ -0,0 +1,23 @@
+; RUN: opt -S -passes=instcombine < %s | FileCheck --check-prefix=BASE %s
+; RUN: opt -S -mtriple=spirv-- -passes=instcombine < %s | FileCheck --check-prefix=SPIR %s
+
+define float @foo(ptr %x) {
+; BASE-LABEL: define float @foo(
+; BASE-SAME: ptr [[X:%.*]]) {
+; BASE-NEXT:  entry:
+; BASE-NEXT:    [[TMP0:%.*]] = getelementptr inbounds nuw i8, ptr [[X]], i64 4
+; BASE-NEXT:    [[TMP1:%.*]] = load float, ptr [[TMP0]], align 4
+; BASE-NEXT:    ret float [[TMP1]]
+;
+; SPIR-LABEL: define float @foo(
+; SPIR-SAME: ptr [[X:%.*]]) {
+; SPIR-NEXT:  entry:
+; SPIR-NEXT:    [[TMP0:%.*]] = getelementptr inbounds nuw <4 x float>, ptr [[X]], i64 0, i64 1
+; SPIR-NEXT:    [[TMP1:%.*]] = load float, ptr [[TMP0]], align 4
+; SPIR-NEXT:    ret float [[TMP1]]
+;
+entry:
+  %3 = getelementptr inbounds nuw <4 x float>, ptr %x, i32 0, i64 1
+  %4 = load float, ptr %3, align 4
+  ret float %4
+}

``````````

</details>


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


More information about the llvm-commits mailing list