blob: 8dd321cd77681d0ee79f950663609e5dfe648aea [file] [edit]
; RUN: llc -mtriple=amdgpu9.42-amd-amdhsa < %s | FileCheck %s
; Regression test for an assertion in the AMDGPU pipeline:
; Assertion `SubRegIdx != 0 && LI.hasSubRanges()' failed.
;
; The machine scheduler's trivial-remat sinking uses the Rematerializer, whose
; incremental live-interval update only created subranges when a *new* user
; read a partial lane mask. A 64-bit VGPR is written subreg-by-subreg and then
; read both as the full register and via .sub0. When the full-register user is
; processed first, subranges were never created, so VirtRegRewriter later asserted
; while inspecting the .sub0 use. The kernel must now compile to valid code without
; crashing.
; CHECK-LABEL: remat_subrange_full_and_partial_use:
; CHECK: s_endpgm
define amdgpu_kernel void @remat_subrange_full_and_partial_use(i32 %arg, ptr addrspace(4) %arg1, ptr addrspace(4) %arg2, ptr addrspace(4) %arg3, ptr addrspace(4) %arg4, ptr addrspace(4) %arg5, ptr addrspace(4) %arg6, ptr addrspace(4) %arg7, ptr addrspace(4) %arg8, ptr addrspace(4) %arg9, ptr addrspace(4) %arg10, ptr addrspace(4) %arg11, ptr addrspace(4) %arg12, ptr addrspace(4) %arg13, ptr addrspace(4) %arg14, ptr addrspace(4) %arg15, ptr addrspace(4) %arg16, ptr addrspace(4) %arg17, ptr addrspace(4) %arg18, ptr addrspace(4) %arg19, <2 x i32> %arg20, ptr addrspace(4) %arg21, i32 %arg22, i32 %arg23, i32 %arg24, i32 %arg25, i32 %arg26, i32 %arg27, i32 %arg28, i32 %arg29, i32 %arg30, i32 %arg31, i32 %arg32, i32 %arg33, i32 %arg34, i32 %arg35, i1 %arg36, i32 %arg37, i32 %arg38, i32 %arg39, i32 %arg40, i32 %arg41, ptr addrspace(1) %arg42, i32 %arg43, i1 %arg44, ptr addrspace(8) %arg45, ptr addrspace(8) %arg46, i32 %arg47, i32 %arg48, i1 %arg49, i1 %arg50, i1 %arg51, i32 %arg52, i1 %arg53) {
bbl:
%load = load i32, ptr addrspace(4) %arg19, align 8
%load54 = load i32, ptr addrspace(4) %arg11, align 4
%load55 = load i32, ptr addrspace(4) %arg1, align 8
%or = or i32 %load55, 1
%icmp = icmp slt i32 0, %or
%icmp56 = icmp slt i32 0, %arg
br i1 %arg36, label %bbl59, label %bbl57
bbl57: ; preds = %bbl
%shl = shl i32 %arg, 1
%or58 = or i32 %shl, 1
br label %bbl59
bbl59: ; preds = %bbl57, %bbl
%or60 = or i32 %arg32, %arg22
%or61 = or i32 %or60, %arg25
%or62 = or i32 %or61, %arg
%call = tail call <2 x i32> @llvm.amdgcn.raw.ptr.buffer.load.v2i32(ptr addrspace(8) null, i32 %or62, i32 0, i32 0)
%and = and i1 %arg49, %icmp56
%and63 = and i1 %arg36, %and
%bitcast = bitcast <2 x i32> %call to <4 x half>
%and64 = and i1 %arg50, %and63
%shufflevector = shufflevector <4 x half> %bitcast, <4 x half> zeroinitializer, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 poison, i32 poison, i32 poison, i32 poison>
%select = select i1 %and64, <8 x half> %shufflevector, <8 x half> zeroinitializer
store <8 x half> %select, ptr addrspace(3) null, align 16
br label %bbl65
bbl65: ; preds = %bbl65, %bbl59
%icmp66 = icmp slt i32 %arg37, 0
%and67 = and i1 %icmp66, %arg44
%call68 = tail call <2 x i32> @llvm.amdgcn.raw.ptr.buffer.load.v2i32(ptr addrspace(8) %arg45, i32 0, i32 0, i32 0)
%bitcast69 = bitcast <2 x i32> %call68 to <4 x half>
%select70 = select i1 %and67, <4 x half> %bitcast69, <4 x half> zeroinitializer
%shufflevector71 = shufflevector <4 x half> %select70, <4 x half> zeroinitializer, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
store <8 x half> %shufflevector71, ptr addrspace(3) null, align 16
br i1 %arg51, label %bbl72, label %bbl65
bbl72: ; preds = %bbl65
%load73 = load float, ptr addrspace(4) %arg5, align 4
%load74 = load i32, ptr addrspace(4) %arg18, align 4
%load75 = load i32, ptr addrspace(4) %arg14, align 4
%mul = mul i32 %load74, %load75
%load76 = load <2 x i32>, ptr addrspace(4) %arg3, align 8
%extractelement = extractelement <2 x i32> %load76, i64 0
%mul77 = mul i32 %mul, %extractelement
%call78 = tail call i16 @llvm.amdgcn.raw.ptr.buffer.load.i16(ptr addrspace(8) null, i32 %mul77, i32 0, i32 0)
%bitcast79 = bitcast i16 %call78 to half
%load80 = load <2 x i32>, ptr addrspace(4) %arg8, align 4
%extractelement81 = extractelement <2 x i32> %load80, i64 0
%load82 = load <2 x i32>, ptr addrspace(4) %arg10, align 4
%extractelement83 = extractelement <2 x i32> %load82, i64 0
%load84 = load <2 x i32>, ptr addrspace(4) %arg13, align 8
%load85 = load i32, ptr addrspace(4) %arg7, align 8
%load86 = load i32, ptr addrspace(4) %arg15, align 8
%mul87 = mul i32 %load85, %load86
%load88 = load <2 x i32>, ptr addrspace(4) %arg1, align 8
%extractelement89 = extractelement <2 x i32> %load88, i64 0
%mul90 = mul i32 %mul87, %extractelement89
%mul91 = mul i32 %extractelement81, %extractelement83
%mul92 = mul i32 %mul91, %arg23
%or93 = or i32 %mul90, %mul92
%lshr = lshr i32 %arg27, %arg26
%extractelement94 = extractelement <2 x i32> %load84, i64 0
%mul95 = mul i32 %lshr, %extractelement94
%or96 = or i32 %or93, %mul95
%icmp97 = icmp slt i32 0, %arg39
%or98 = or i32 %arg40, %arg41
%icmp99 = icmp slt i32 0, %or98
%and100 = and i1 %icmp97, %icmp99
%fcmp = fcmp ogt half %bitcast79, 0.000000e+00
%fptrunc = fptrunc float %load73 to half
%select101 = select i1 %fcmp, half 0.000000e+00, half %fptrunc
%select102 = select i1 %and100, half %select101, half 0.000000e+00
%insertelement = insertelement <4 x half> zeroinitializer, half %select102, i64 0
%bitcast103 = bitcast <4 x half> %insertelement to <2 x i32>
tail call void @llvm.amdgcn.raw.ptr.buffer.store.v2i32(<2 x i32> %bitcast103, ptr addrspace(8) %arg46, i32 0, i32 0, i32 0)
%load104 = load <2 x i32>, ptr addrspace(4) %arg6, align 8
%load105 = load <2 x i32>, ptr addrspace(4) %arg9, align 4
%load106 = load i32, ptr addrspace(4) %arg12, align 4
%load107 = load i32, ptr addrspace(4) %arg17, align 4
%lshr108 = lshr i32 %load106, %load107
%load109 = load i32, ptr addrspace(4) %arg16, align 8
%mul110 = mul i32 %load, %load109
%mul111 = mul i32 %mul110, %arg52
%mul112 = mul i32 %lshr108, %load54
%mul113 = mul i32 %mul112, %arg24
%or114 = or i32 %mul111, %mul113
%or115 = or i32 %or114, %arg33
%or116 = or i32 %or115, %arg28
%extractelement117 = extractelement <2 x i32> %load104, i64 0
%extractelement118 = extractelement <2 x i32> %load105, i64 0
%lshr119 = lshr i32 %extractelement117, %extractelement118
%load120 = load <2 x i32>, ptr addrspace(4) %arg2, align 4
%extractelement121 = extractelement <2 x i32> %load120, i64 0
%mul122 = mul i32 %lshr119, %extractelement121
%insertelement123 = insertelement <2 x i32> zeroinitializer, i32 %mul122, i64 1
%mul124 = mul <2 x i32> %insertelement123, %arg20
%extractelement125 = extractelement <2 x i32> %mul124, i64 1
%icmp126 = icmp slt i32 0, %arg34
%load127 = load i32, ptr addrspace(4) %arg4, align 8
%icmp128 = icmp sge i32 0, %load127
%select129 = select i1 %icmp128, i1 %arg53, i1 false
%and130 = and i1 %icmp126, %select129
%icmp131 = icmp slt i32 0, %arg38
%or132 = or i32 %or96, %arg29
%call133 = tail call i16 @llvm.amdgcn.raw.ptr.buffer.load.i16(ptr addrspace(8) null, i32 %or132, i32 0, i32 0)
%bitcast134 = bitcast i16 %call133 to half
%select135 = select i1 %icmp131, half %bitcast134, half 0.000000e+00
%insertelement136 = insertelement <4 x half> zeroinitializer, half %select135, i64 0
%bitcast137 = bitcast <4 x half> %insertelement136 to <2 x i32>
%or138 = or i32 %or116, %extractelement125
%select139 = select i1 %and130, i32 0, i32 1
%or140 = or i32 %or138, %select139
tail call void @llvm.amdgcn.raw.ptr.buffer.store.v2i32(<2 x i32> %bitcast137, ptr addrspace(8) null, i32 %or140, i32 0, i32 0)
ret void
}
declare <2 x i32> @llvm.amdgcn.raw.ptr.buffer.load.v2i32(ptr addrspace(8) readonly captures(none), i32, i32, i32 immarg) #0
declare i16 @llvm.amdgcn.raw.ptr.buffer.load.i16(ptr addrspace(8) readonly captures(none), i32, i32, i32 immarg) #0
declare void @llvm.amdgcn.raw.ptr.buffer.store.v2i32(<2 x i32>, ptr addrspace(8) writeonly captures(none), i32, i32, i32 immarg) #1
attributes #0 = { nocallback nofree nosync nounwind willreturn memory(argmem: read) }
attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: write) }