[llvm] [LSR] Fix ICmpZero type mismatch with mixed-width pointers (PR #206193)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Sat Jun 27 01:57:07 PDT 2026


================
@@ -0,0 +1,90 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -passes=loop-reduce -S -mcpu=gfx942 %s | FileCheck %s
+; REQUIRES: amdgpu-registered-target
+;
+; Verify that LSR produces well-typed icmp operands when ICmpZero uses a
+; pointer-typed operand from a narrow address space (addrspace(5), 32-bit)
+; but the chosen IV is wider (i64, from flat-pointer address uses).
+
+target datalayout = "e-m:e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-p7:160:256:256:32-p8:128:128:128:48-p9:192:256:256:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8:9"
+target triple = "amdgcn-amd-amdhsa"
+
+
+define amdgpu_kernel void @icmpzero_mixed_ptr_width(ptr addrspace(5) %scratch) {
+; CHECK-LABEL: define amdgpu_kernel void @icmpzero_mixed_ptr_width(
+; CHECK-SAME: ptr addrspace(5) [[SCRATCH:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    br label %[[LOOP:.*]]
+; CHECK:       [[LOOP]]:
+; CHECK-NEXT:    [[LSR_IV:%.*]] = phi i64 [ [[LSR_IV_NEXT:%.*]], %[[LATCH:.*]] ], [ 0, %[[ENTRY]] ]
+; CHECK-NEXT:    [[DST:%.*]] = phi ptr addrspace(5) [ [[SCRATCH]], %[[ENTRY]] ], [ [[DST_NEXT:%.*]], %[[LATCH]] ]
+; CHECK-NEXT:    [[SCEVGEP4:%.*]] = getelementptr i8, ptr null, i64 [[LSR_IV]]
+; CHECK-NEXT:    [[D0:%.*]] = load double, ptr addrspace(5) [[DST]], align 8
+; CHECK-NEXT:    [[S0:%.*]] = load double, ptr [[SCEVGEP4]], align 8
+; CHECK-NEXT:    [[CMP0:%.*]] = fcmp ueq double [[D0]], [[S0]]
+; CHECK-NEXT:    br i1 [[CMP0]], label %[[IF1:.*]], label %[[LATCH]]
+; CHECK:       [[IF1]]:
+; CHECK-NEXT:    [[DST_1:%.*]] = getelementptr i8, ptr addrspace(5) [[DST]], i32 8
+; CHECK-NEXT:    [[D1:%.*]] = load double, ptr addrspace(5) [[DST_1]], align 8
+; CHECK-NEXT:    [[SCEVGEP2:%.*]] = getelementptr i8, ptr null, i64 [[LSR_IV]]
+; CHECK-NEXT:    [[SCEVGEP3:%.*]] = getelementptr i8, ptr [[SCEVGEP2]], i64 8
+; CHECK-NEXT:    [[S1:%.*]] = load double, ptr [[SCEVGEP3]], align 8
+; CHECK-NEXT:    [[CMP1:%.*]] = fcmp ueq double [[D1]], [[S1]]
+; CHECK-NEXT:    br i1 [[CMP1]], label %[[IF2:.*]], label %[[LATCH]]
+; CHECK:       [[IF2]]:
+; CHECK-NEXT:    [[DST_2:%.*]] = getelementptr i8, ptr addrspace(5) [[DST]], i32 16
+; CHECK-NEXT:    [[D2:%.*]] = load double, ptr addrspace(5) [[DST_2]], align 8
+; CHECK-NEXT:    [[SCEVGEP:%.*]] = getelementptr i8, ptr null, i64 [[LSR_IV]]
+; CHECK-NEXT:    [[SCEVGEP1:%.*]] = getelementptr i8, ptr [[SCEVGEP]], i64 16
+; CHECK-NEXT:    [[S2:%.*]] = load double, ptr [[SCEVGEP1]], align 8
+; CHECK-NEXT:    [[CMP2:%.*]] = fcmp ueq double [[D2]], [[S2]]
+; CHECK-NEXT:    br i1 [[CMP2]], label %[[EARLY_EXIT:.*]], label %[[LATCH]]
+; CHECK:       [[EARLY_EXIT]]:
+; CHECK-NEXT:    ret void
+; CHECK:       [[LATCH]]:
+; CHECK-NEXT:    [[DST_NEXT]] = getelementptr i8, ptr addrspace(5) [[DST]], i32 96
+; CHECK-NEXT:    [[LSR_IV_NEXT]] = add nuw nsw i64 [[LSR_IV]], 96
+; CHECK-NEXT:    [[DONE:%.*]] = icmp eq i64 [[LSR_IV_NEXT]], 96
+; CHECK-NEXT:    br i1 [[DONE]], label %[[EXIT:.*]], label %[[LOOP]]
+; CHECK:       [[EXIT]]:
+; CHECK-NEXT:    ret void
+;
+entry:
+  br label %loop
+
+loop:
+  %src = phi ptr [ null, %entry ], [ %src.next, %latch ]
+  %dst = phi ptr addrspace(5) [ %scratch, %entry ], [ %dst.next, %latch ]
+  %d0 = load double, ptr addrspace(5) %dst, align 8
+  %s0 = load double, ptr %src, align 8
+  %cmp0 = fcmp ueq double %d0, %s0
+  br i1 %cmp0, label %if1, label %latch
+
+if1:
+  %dst.1 = getelementptr i8, ptr addrspace(5) %dst, i32 8
+  %d1 = load double, ptr addrspace(5) %dst.1, align 8
+  %src.1 = getelementptr i8, ptr %src, i64 8
+  %s1 = load double, ptr %src.1, align 8
+  %cmp1 = fcmp ueq double %d1, %s1
+  br i1 %cmp1, label %if2, label %latch
+
+if2:
+  %dst.2 = getelementptr i8, ptr addrspace(5) %dst, i32 16
+  %d2 = load double, ptr addrspace(5) %dst.2, align 8
+  %src.2 = getelementptr i8, ptr %src, i64 16
+  %s2 = load double, ptr %src.2, align 8
+  %cmp2 = fcmp ueq double %d2, %s2
+  br i1 %cmp2, label %early.exit, label %latch
----------------
nikic wrote:

Does the issue still reproduce with a simplified test case (e.g. do we need both of these if blocks)?

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


More information about the llvm-commits mailing list