245 lines · plain
1; RUN: llc -mtriple=amdgcn -mcpu=gfx900 -global-isel=0 -stop-after=finalize-isel -o - %s | FileCheck -check-prefixes=GCN,SDAG %s2; RUN: llc -mtriple=amdgcn -mcpu=gfx900 -global-isel=1 -stop-after=finalize-isel -o - %s | FileCheck -check-prefixes=GCN,GISEL %s3 4@0 = external dso_local addrspace(4) constant [4 x <2 x float>]5@1 = external dso_local addrspace(4) constant i326 7; Test that DAG->DAG ISel is able to pick up the S_LOAD_DWORDX4_SGPR instruction that fetches the offset8; from a register.9; GCN-LABEL: name: test_load_zext10; GCN: %[[OFFSET:[0-9]+]]:sreg_32 = S_MOV_B32 target-flags(amdgpu-abs32-lo) @DescriptorBuffer11; SDAG: %{{[0-9]+}}:sgpr_128 = S_LOAD_DWORDX4_SGPR_IMM killed %{{[0-9]+}}, killed %[[OFFSET]], 0, 0 :: (invariant load (s128) from %ir.12, addrspace 4)12; GISEL: %{{[0-9]+}}:sgpr_128 = S_LOAD_DWORDX4_SGPR_IMM %{{[0-9]+}}, %[[OFFSET]], 0, 0 :: (invariant load (<4 x s32>) from {{.*}}, addrspace 4)13define amdgpu_cs void @test_load_zext(i32 inreg %0, i32 inreg %1, i32 inreg %resNode0, i32 inreg %resNode1, <3 x i32> inreg %2, i32 inreg %3, <3 x i32> %4) local_unnamed_addr #2 {14.entry:15 %5 = call i64 @llvm.amdgcn.s.getpc() #316 %6 = bitcast i64 %5 to <2 x i32>17 %7 = insertelement <2 x i32> %6, i32 %resNode0, i32 018 %8 = bitcast <2 x i32> %7 to i6419 %9 = inttoptr i64 %8 to ptr addrspace(4)20 %10 = call i32 @llvm.amdgcn.reloc.constant(metadata !4)21 %11 = zext i32 %10 to i6422 %12 = getelementptr [4294967295 x i8], ptr addrspace(4) %9, i64 0, i64 %1123 %13 = load <4 x i32>, ptr addrspace(4) %12, align 16, !invariant.load !524 %.13.as.int = bitcast <4 x i32> %13 to i12825 %.13.as.ptr = inttoptr i128 %.13.as.int to ptr addrspace(8)26 %14 = call <4 x i32> @llvm.amdgcn.s.buffer.load.v4i32(<4 x i32> %13, i32 0, i32 0)27 call void @llvm.amdgcn.raw.ptr.buffer.store.v4i32(<4 x i32> %14, ptr addrspace(8) %.13.as.ptr, i32 0, i32 0, i32 0)28 ret void29}30 31; Make sure we match constant bases with register offests, in which case32; the base may be the RHS operand of the load in SDAG.33; GCN-LABEL: name: test_complex_reg_offset34; GCN-DAG: %[[BASE:.*]]:sreg_64 = SI_PC_ADD_REL_OFFSET target-flags(amdgpu-rel32-lo) @0,35; SDAG-DAG: %[[OFFSET:.*]]:sreg_32 = nuw nsw S_LSHL_B3236; GISEL-DAG: %[[OFFSET:.*]]:sreg_32 = S_LSHL_B3237; SDAG: S_LOAD_DWORD_SGPR_IMM killed %[[BASE]], killed %[[OFFSET]], 0, 038; GISEL: S_LOAD_DWORD_SGPR_IMM %[[BASE]], %[[OFFSET]], 0, 039define amdgpu_ps void @test_complex_reg_offset(ptr addrspace(1) %out) {40 %i = load i32, ptr addrspace(4) @141 %i1 = and i32 %i, 342 %i2 = zext i32 %i1 to i6443 %i3 = getelementptr [4 x <2 x float>], ptr addrspace(4) @0, i64 0, i64 %i2, i64 044 %i4 = load float, ptr addrspace(4) %i3, align 445 store float %i4, ptr addrspace(1) %out46 ret void47}48 49; GCN-LABEL: name: test_sgpr_plus_imm_offset50; SDAG-DAG: %[[BASE0:.*]]:sgpr_32 = COPY $sgpr051; SDAG-DAG: %[[BASE1:.*]]:sgpr_32 = COPY $sgpr152; SDAG-DAG: %[[OFFSET:.*]]:sgpr_32 = COPY $sgpr253; SDAG-DAG: %[[BASE:.*]]:sgpr_64 = REG_SEQUENCE %[[BASE0]], %subreg.sub0, %[[BASE1]], %subreg.sub154; SDAG: S_LOAD_DWORD_SGPR_IMM killed %[[BASE]], %[[OFFSET]], 16,55; GISEL-DAG: %[[BASE0:.*]]:sreg_32 = COPY $sgpr056; GISEL-DAG: %[[BASE1:.*]]:sreg_32 = COPY $sgpr157; GISEL-DAG: %[[OFFSET:.*]]:sreg_32 = COPY $sgpr258; GISEL-DAG: %[[BASE:.*]]:sreg_64 = REG_SEQUENCE %[[BASE0]], %subreg.sub0, %[[BASE1]], %subreg.sub159; GISEL: S_LOAD_DWORD_SGPR_IMM %[[BASE]], %[[OFFSET]], 16,60define amdgpu_ps void @test_sgpr_plus_imm_offset(ptr addrspace(4) inreg %base, i32 inreg %offset,61 ptr addrspace(1) inreg %out) {62 %v1 = getelementptr i8, ptr addrspace(4) %base, i64 1663 %v2 = zext i32 %offset to i6464 %v3 = getelementptr i8, ptr addrspace(4) %v1, i64 %v265 %v5 = load i32, ptr addrspace(4) %v3, align 466 store i32 %v5, ptr addrspace(1) %out, align 467 ret void68}69 70; GCN-LABEL: name: test_sgpr_plus_imm_offset_x271; SDAG-DAG: %[[BASE0:.*]]:sgpr_32 = COPY $sgpr072; SDAG-DAG: %[[BASE1:.*]]:sgpr_32 = COPY $sgpr173; SDAG-DAG: %[[OFFSET:.*]]:sgpr_32 = COPY $sgpr274; SDAG-DAG: %[[BASE:.*]]:sgpr_64 = REG_SEQUENCE %[[BASE0]], %subreg.sub0, %[[BASE1]], %subreg.sub175; SDAG: S_LOAD_DWORDX2_SGPR_IMM_ec killed %[[BASE]], %[[OFFSET]], 16,76; GISEL-DAG: %[[BASE0:.*]]:sreg_32 = COPY $sgpr077; GISEL-DAG: %[[BASE1:.*]]:sreg_32 = COPY $sgpr178; GISEL-DAG: %[[OFFSET:.*]]:sreg_32 = COPY $sgpr279; GISEL-DAG: %[[BASE:.*]]:sreg_64 = REG_SEQUENCE %[[BASE0]], %subreg.sub0, %[[BASE1]], %subreg.sub180; GISEL: S_LOAD_DWORDX2_SGPR_IMM_ec %[[BASE]], %[[OFFSET]], 16,81define amdgpu_ps void @test_sgpr_plus_imm_offset_x2(ptr addrspace(4) inreg %base, i32 inreg %offset,82 ptr addrspace(1) inreg %out) {83 %v1 = getelementptr i8, ptr addrspace(4) %base, i64 1684 %v2 = zext i32 %offset to i6485 %v3 = getelementptr i8, ptr addrspace(4) %v1, i64 %v286 %v5 = load <2 x i32>, ptr addrspace(4) %v3, align 487 store <2 x i32> %v5, ptr addrspace(1) %out, align 488 ret void89}90 91; GCN-LABEL: name: test_buffer_load_sgpr_plus_imm_offset92; SDAG-DAG: %[[BASE0:.*]]:sgpr_32 = COPY $sgpr093; SDAG-DAG: %[[BASE1:.*]]:sgpr_32 = COPY $sgpr194; SDAG-DAG: %[[BASE2:.*]]:sgpr_32 = COPY $sgpr295; SDAG-DAG: %[[BASE3:.*]]:sgpr_32 = COPY $sgpr396; SDAG-DAG: %[[OFFSET:.*]]:sgpr_32 = COPY $sgpr497; SDAG-DAG: %[[BASE:.*]]:sgpr_128 = REG_SEQUENCE %[[BASE0]], %subreg.sub0, %[[BASE1]], %subreg.sub1, %[[BASE2]], %subreg.sub2, %[[BASE3]], %subreg.sub398; SDAG: S_BUFFER_LOAD_DWORD_SGPR_IMM killed %[[BASE]], %[[OFFSET]], 77,99; GISEL-DAG: %[[BASE0:.*]]:sreg_32 = COPY $sgpr0100; GISEL-DAG: %[[BASE1:.*]]:sreg_32 = COPY $sgpr1101; GISEL-DAG: %[[BASE2:.*]]:sreg_32 = COPY $sgpr2102; GISEL-DAG: %[[BASE3:.*]]:sreg_32 = COPY $sgpr3103; GISEL-DAG: %[[OFFSET:.*]]:sreg_32 = COPY $sgpr4104; GISEL-DAG: %[[BASE:.*]]:sgpr_128 = REG_SEQUENCE %[[BASE0]], %subreg.sub0, %[[BASE1]], %subreg.sub1, %[[BASE2]], %subreg.sub2, %[[BASE3]], %subreg.sub3105; GISEL: S_BUFFER_LOAD_DWORD_SGPR_IMM %[[BASE]], %[[OFFSET]], 77,106define amdgpu_cs void @test_buffer_load_sgpr_plus_imm_offset(<4 x i32> inreg %base, i32 inreg %i, ptr addrspace(1) inreg %out) {107 %off = add nuw nsw i32 %i, 77108 %v = call i32 @llvm.amdgcn.s.buffer.load.i32(<4 x i32> %base, i32 %off, i32 0)109 store i32 %v, ptr addrspace(1) %out, align 4110 ret void111}112 113; GCN-LABEL: name: test_buffer_load_sgpr_plus_imm_offset_nuw114; SDAG-DAG: %[[BASE0:.*]]:sgpr_32 = COPY $sgpr0115; SDAG-DAG: %[[BASE1:.*]]:sgpr_32 = COPY $sgpr1116; SDAG-DAG: %[[BASE2:.*]]:sgpr_32 = COPY $sgpr2117; SDAG-DAG: %[[BASE3:.*]]:sgpr_32 = COPY $sgpr3118; SDAG-DAG: %[[OFFSET:.*]]:sgpr_32 = COPY $sgpr4119; SDAG-DAG: %[[BASE:.*]]:sgpr_128 = REG_SEQUENCE %[[BASE0]], %subreg.sub0, %[[BASE1]], %subreg.sub1, %[[BASE2]], %subreg.sub2, %[[BASE3]], %subreg.sub3120; SDAG: S_BUFFER_LOAD_DWORD_SGPR_IMM killed %[[BASE]], %[[OFFSET]], 77,121; GISEL-DAG: %[[BASE0:.*]]:sreg_32 = COPY $sgpr0122; GISEL-DAG: %[[BASE1:.*]]:sreg_32 = COPY $sgpr1123; GISEL-DAG: %[[BASE2:.*]]:sreg_32 = COPY $sgpr2124; GISEL-DAG: %[[BASE3:.*]]:sreg_32 = COPY $sgpr3125; GISEL-DAG: %[[OFFSET:.*]]:sreg_32 = COPY $sgpr4126; GISEL-DAG: %[[BASE:.*]]:sgpr_128 = REG_SEQUENCE %[[BASE0]], %subreg.sub0, %[[BASE1]], %subreg.sub1, %[[BASE2]], %subreg.sub2, %[[BASE3]], %subreg.sub3127; GISEL: S_BUFFER_LOAD_DWORD_SGPR_IMM %[[BASE]], %[[OFFSET]], 77,128define amdgpu_cs void @test_buffer_load_sgpr_plus_imm_offset_nuw(<4 x i32> inreg %base, i32 inreg %i, ptr addrspace(1) inreg %out) #0 {129 %off = add nuw i32 %i, 77130 %v = call i32 @llvm.amdgcn.s.buffer.load.i32(<4 x i32> %base, i32 %off, i32 0)131 store i32 %v, ptr addrspace(1) %out, align 4132 ret void133}134 135; GCN-LABEL: name: test_buffer_load_sgpr_plus_imm_offset_nsw136; SDAG-DAG: %[[BASE0:.*]]:sgpr_32 = COPY $sgpr0137; SDAG-DAG: %[[BASE1:.*]]:sgpr_32 = COPY $sgpr1138; SDAG-DAG: %[[BASE2:.*]]:sgpr_32 = COPY $sgpr2139; SDAG-DAG: %[[BASE3:.*]]:sgpr_32 = COPY $sgpr3140; SDAG-DAG: %[[OFFSET:.*]]:sgpr_32 = COPY $sgpr4141; SDAG-DAG: %[[BASE:.*]]:sgpr_128 = REG_SEQUENCE %[[BASE0]], %subreg.sub0, %[[BASE1]], %subreg.sub1, %[[BASE2]], %subreg.sub2, %[[BASE3]], %subreg.sub3142; SDAG-DAG: %[[ADD:.*]]:sreg_32 = nsw S_ADD_I32 %4, killed %11, implicit-def dead $scc143; SDAG: S_BUFFER_LOAD_DWORD_SGPR_IMM killed %[[BASE]], killed %[[ADD]], 0,144; GISEL-DAG: %[[BASE0:.*]]:sreg_32 = COPY $sgpr0145; GISEL-DAG: %[[BASE1:.*]]:sreg_32 = COPY $sgpr1146; GISEL-DAG: %[[BASE2:.*]]:sreg_32 = COPY $sgpr2147; GISEL-DAG: %[[BASE3:.*]]:sreg_32 = COPY $sgpr3148; GISEL-DAG: %[[OFFSET:.*]]:sreg_32 = COPY $sgpr4149; GISEL-DAG: %[[BASE:.*]]:sgpr_128 = REG_SEQUENCE %[[BASE0]], %subreg.sub0, %[[BASE1]], %subreg.sub1, %[[BASE2]], %subreg.sub2, %[[BASE3]], %subreg.sub3150; GISEL-DAG: %[[ADD:.*]]:sreg_32 = nsw S_ADD_I32 %1, %10, implicit-def dead $scc151; GISEL: S_BUFFER_LOAD_DWORD_SGPR_IMM %[[BASE]], %[[ADD]], 0,152define amdgpu_cs void @test_buffer_load_sgpr_plus_imm_offset_nsw(<4 x i32> inreg %base, i32 inreg %i, ptr addrspace(1) inreg %out) #0 {153 %off = add nsw i32 %i, 77154 %v = call i32 @llvm.amdgcn.s.buffer.load.i32(<4 x i32> %base, i32 %off, i32 0)155 store i32 %v, ptr addrspace(1) %out, align 4156 ret void157 }158 159; GCN-LABEL: name: test_buffer_load_sgpr_plus_imm_offset_noflags160; SDAG-DAG: %[[BASE0:.*]]:sgpr_32 = COPY $sgpr0161; SDAG-DAG: %[[BASE1:.*]]:sgpr_32 = COPY $sgpr1162; SDAG-DAG: %[[BASE2:.*]]:sgpr_32 = COPY $sgpr2163; SDAG-DAG: %[[BASE3:.*]]:sgpr_32 = COPY $sgpr3164; SDAG-DAG: %[[OFFSET:.*]]:sgpr_32 = COPY $sgpr4165; SDAG-DAG: %[[BASE:.*]]:sgpr_128 = REG_SEQUENCE %[[BASE0]], %subreg.sub0, %[[BASE1]], %subreg.sub1, %[[BASE2]], %subreg.sub2, %[[BASE3]], %subreg.sub3166; SDAG-DAG: %[[ADD:.*]]:sreg_32 = S_ADD_I32 %4, killed %11, implicit-def dead $scc167; SDAG: S_BUFFER_LOAD_DWORD_SGPR_IMM killed %[[BASE]], killed %[[ADD]], 0,168; GISEL-DAG: %[[BASE0:.*]]:sreg_32 = COPY $sgpr0169; GISEL-DAG: %[[BASE1:.*]]:sreg_32 = COPY $sgpr1170; GISEL-DAG: %[[BASE2:.*]]:sreg_32 = COPY $sgpr2171; GISEL-DAG: %[[BASE3:.*]]:sreg_32 = COPY $sgpr3172; GISEL-DAG: %[[OFFSET:.*]]:sreg_32 = COPY $sgpr4173; GISEL-DAG: %[[BASE:.*]]:sgpr_128 = REG_SEQUENCE %[[BASE0]], %subreg.sub0, %[[BASE1]], %subreg.sub1, %[[BASE2]], %subreg.sub2, %[[BASE3]], %subreg.sub3174; GISEL-DAG: %[[ADD:.*]]:sreg_32 = S_ADD_I32 %1, %10, implicit-def dead $scc175; GISEL: S_BUFFER_LOAD_DWORD_SGPR_IMM %[[BASE]], %[[ADD]], 0,176define amdgpu_cs void @test_buffer_load_sgpr_plus_imm_offset_noflags(<4 x i32> inreg %base, i32 inreg %i, ptr addrspace(1) inreg %out) #0 {177 %off = add i32 %i, 77178 %v = call i32 @llvm.amdgcn.s.buffer.load.i32(<4 x i32> %base, i32 %off, i32 0)179 store i32 %v, ptr addrspace(1) %out, align 4180 ret void181 }182 183; GCN-LABEL: name: test_buffer_load_sgpr_or_imm_offset184; SDAG-DAG: %[[BASE0:.*]]:sgpr_32 = COPY $sgpr0185; SDAG-DAG: %[[BASE1:.*]]:sgpr_32 = COPY $sgpr1186; SDAG-DAG: %[[BASE2:.*]]:sgpr_32 = COPY $sgpr2187; SDAG-DAG: %[[BASE3:.*]]:sgpr_32 = COPY $sgpr3188; SDAG-DAG: %[[INDEX:.*]]:sgpr_32 = COPY $sgpr4189; SDAG-DAG: %[[SHIFT:.*]]:sreg_32 = S_LSHL_B32 %[[INDEX]],190; SDAG-DAG: %[[BASE:.*]]:sgpr_128 = REG_SEQUENCE %[[BASE0]], %subreg.sub0, %[[BASE1]], %subreg.sub1, %[[BASE2]], %subreg.sub2, %[[BASE3]], %subreg.sub3191; SDAG: S_BUFFER_LOAD_DWORD_SGPR_IMM killed %[[BASE]], killed %[[SHIFT]], 5,192; GISEL-DAG: %[[BASE0:.*]]:sreg_32 = COPY $sgpr0193; GISEL-DAG: %[[BASE1:.*]]:sreg_32 = COPY $sgpr1194; GISEL-DAG: %[[BASE2:.*]]:sreg_32 = COPY $sgpr2195; GISEL-DAG: %[[BASE3:.*]]:sreg_32 = COPY $sgpr3196; GISEL-DAG: %[[INDEX:.*]]:sreg_32 = COPY $sgpr4197; GISEL-DAG: %[[SHIFT:.*]]:sreg_32 = S_LSHL_B32 %[[INDEX]],198; GISEL-DAG: %[[BASE:.*]]:sgpr_128 = REG_SEQUENCE %[[BASE0]], %subreg.sub0, %[[BASE1]], %subreg.sub1, %[[BASE2]], %subreg.sub2, %[[BASE3]], %subreg.sub3199; GISEL: S_BUFFER_LOAD_DWORD_SGPR_IMM %[[BASE]], %[[SHIFT]], 5,200define amdgpu_cs void @test_buffer_load_sgpr_or_imm_offset(<4 x i32> inreg %base, i32 inreg %i, ptr addrspace(1) inreg %out) {201 %shift = shl i32 %i, 7202 %off = or i32 %shift, 5203 %v = call i32 @llvm.amdgcn.s.buffer.load.i32(<4 x i32> %base, i32 %off, i32 0)204 store i32 %v, ptr addrspace(1) %out, align 4205 ret void206}207 208declare void @llvm.amdgcn.raw.ptr.buffer.store.v4i32(<4 x i32>, ptr addrspace(8) nocapture, i32, i32, i32 immarg) #1209 210declare i32 @llvm.amdgcn.s.buffer.load.i32(<4 x i32>, i32, i32 immarg) nounwind readnone willreturn211 212; Function Attrs: nounwind readnone speculatable213declare i32 @llvm.amdgcn.reloc.constant(metadata) #3214 215; Function Attrs: nounwind readnone speculatable216declare i64 @llvm.amdgcn.s.getpc() #3217 218; Function Attrs: nounwind readnone219declare <4 x i32> @llvm.amdgcn.s.buffer.load.v4i32(<4 x i32>, i32, i32 immarg) #1220 221attributes #0 = { argmemonly nounwind willreturn }222attributes #1 = { nounwind memory(argmem: write) }223attributes #2 = { nounwind "amdgpu-unroll-threshold"="700" }224attributes #3 = { nounwind readnone speculatable }225attributes #4 = { nounwind writeonly }226 227!llpc.compute.mode = !{!0}228!llpc.options = !{!1}229!llpc.options.CS = !{!2}230!llpc.user.data.nodes = !{!3, !4, !5, !6}231!amdgpu.pal.metadata.msgpack = !{!7}232 233!0 = !{i32 2, i32 3, i32 1}234!1 = !{i32 245227952, i32 996822128, i32 2024708198, i32 497230408}235!2 = !{i32 1381820427, i32 1742110173, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 64}236!3 = !{!"DescriptorTableVaPtr", i32 0, i32 1, i32 1}237!4 = !{!"DescriptorBuffer", i32 4, i32 8, i32 0, i32 0}238!5 = !{!"DescriptorTableVaPtr", i32 1, i32 1, i32 1}239!6 = !{!"DescriptorBuffer", i32 4, i32 8, i32 1, i32 0}240!7 = !{!"\82\B0amdpal.pipelines\91\88\A4.api\A6Vulkan\B0.hardware_stages\81\A3.cs\82\AB.sgpr_limith\AB.vgpr_limit\CD\01\00\B7.internal_pipeline_hash\92\CF;jLp\0E\9D\E1\B0\CF\1D\A3\22Hx\AE\98f\AA.registers\88\CD.\07\02\CD.\08\03\CD.\09\01\CD.\12\CE\00,\00\00\CD.\13\CD\0F\88\CD.@\CE\10\00\00\00\CD.B\00\CD.C\01\A8.shaders\81\A8.compute\82\B0.api_shader_hash\92\CFg\D6}\DDR\\\E8\0B\00\B1.hardware_mapping\91\A3.cs\B0.spill_threshold\CE\FF\FF\FF\FF\A5.type\A2Cs\B0.user_data_limit\02\AEamdpal.version\92\02\03"}241!8 = !{i32 5}242!9 = !{!"doff_0_0_b"}243!10 = !{}244!11 = !{!"doff_1_0_b"}245