diff --git a/lgc/builder/BuilderImpl.cpp b/lgc/builder/BuilderImpl.cpp index bf98da645e..b81d5898e3 100644 --- a/lgc/builder/BuilderImpl.cpp +++ b/lgc/builder/BuilderImpl.cpp @@ -398,21 +398,13 @@ class TraceNonUniformIndex { // Maps non-uniform operands with the scalarization option. bool scalarizeDescriptorLoads; unsigned upperLimit; + unsigned cnt = 0; + void init(Instruction *); void insertNewValueInInstrDeps(Value *, Instruction *); public: TraceNonUniformIndex(Instruction *nonUniformInst, bool scalarizeDescriptorLoads = false, unsigned upperLimit = 64) - : scalarizeDescriptorLoads(scalarizeDescriptorLoads), upperLimit(upperLimit) { - // Initialization of instrToIndex and indexToInstr. - if (scalarizeDescriptorLoads) { - unsigned cnt = 0; - for (Instruction *I = nonUniformInst->getPrevNode(); I != nullptr && cnt < upperLimit; - I = I->getPrevNode(), ++cnt) { - indexToInstr.push_back(I); - instrToIndex[I] = cnt; - } - } - } + : scalarizeDescriptorLoads(scalarizeDescriptorLoads), upperLimit(upperLimit) {} Value *run(Value *); @@ -421,6 +413,12 @@ class TraceNonUniformIndex { const TinyInstructionSet::IndexToInstructionVec &getIndexToInstr() const { return indexToInstr; } }; +void TraceNonUniformIndex::init(Instruction *instr) { + indexToInstr.push_back(instr); + instrToIndex[instr] = cnt; + cnt++; +} + // Adds newValue in instrDeps map. The dependencies of the newValue are the currentVisitedInstr and its dependencies. // @param newValue : the new value to be added in instrDeps map // @param currentVisitedInstr : the value from where we copy the dependencies for newValue @@ -428,8 +426,8 @@ void TraceNonUniformIndex::insertNewValueInInstrDeps(Value *newValue, Instructio if (!instrToIndex.contains(currentVisitedInstr)) // The instruction is either outside of 64 limit or in a different basic block. So, we bail-out scalarization. return; - assert(instrDeps.contains(currentVisitedInstr) && "The current visited instruction should have been in the map."); + init(cast(newValue)); auto it1 = instrDeps.try_emplace(newValue, upperLimit).first; auto &setOfInstrs = it1->second; auto it2 = instrDeps.find(currentVisitedInstr); @@ -457,6 +455,7 @@ void TraceNonUniformIndex::insertNewValueInInstrDeps(Value *newValue, Instructio Value *TraceNonUniformIndex::run(Value *nonUniformVal) { auto load = dyn_cast(nonUniformVal); if (scalarizeDescriptorLoads && load) { + init(load); instrDeps.try_emplace(load, upperLimit); } else if (!load) { // Workarounds that modify image descriptor can be peeped through, i.e. @@ -468,8 +467,10 @@ Value *TraceNonUniformIndex::run(Value *nonUniformVal) { if (!insert) return nonUniformVal; - if (scalarizeDescriptorLoads) + if (scalarizeDescriptorLoads) { + init(insert); instrDeps.try_emplace(insert, upperLimit); + } load = dyn_cast(insert->getOperand(0)); if (!load) @@ -659,7 +660,7 @@ static bool instructionsEqual(Instruction *lhs, Instruction *rhs) { } // ===================================================================================================================== -// Exttract the 32-bit value of the non-uniform index. +// Extract the 32-bit value of the non-uniform index. // @param nonUniformIndex : the non-uniform index of the non-uniform operand of the image call // @return : the 32-bit value of the nonUniformIndex Value *get32BitNonUniformIndex(Value *nonUniformIndex) { @@ -698,14 +699,13 @@ Value *getSharedIndex(ArrayRef nonUniformIndices, DenseMap &instrDeps = traceNonUniformIndex.getInstrDeps(); auto it = instrDeps.find(nonUniformIndex); bool hasDependencies = it != instrDeps.end(); - if (!nonUniformInstr || - (firstIndexInst && (!instructionsEqual(nonUniformInstr, firstIndexInst) || - nonUniformInstr->getParent() != firstIndexInst->getParent())) || + if (!nonUniformInstr || (firstIndexInst && !instructionsEqual(nonUniformInstr, firstIndexInst)) || !hasDependencies) { identicalIndexes = false; return nullptr; } - if (!firstIndexInst || nonUniformInstr->comesBefore(firstIndexInst)) + if (!firstIndexInst || (firstIndexInst && nonUniformInstr->getParent() == firstIndexInst->getParent() && + nonUniformInstr->comesBefore(firstIndexInst))) firstIndexInst = nonUniformInstr; } return firstIndexInst; @@ -808,7 +808,7 @@ Instruction *BuilderImpl::createWaterfallLoop(Instruction *nonUniformInst, Array auto itDep = instrDeps.find(nonUniformIndex); // Move the non-uniform loads inside the loop. - if (scalarizeDescriptorLoads && nonUniformIndex != nonUniformImageCallOperand && itDep != instrDeps.end()) { + if (scalarizeDescriptorLoads && itDep != instrDeps.end()) { Value *nonUniformIndex32Bit = nonUniformIndex->getType()->isIntegerTy(64) ? nonUniformIndex32BitVal[nonUniformIndex] : nonUniformIndex; diff --git a/lgc/test/scalarizationOfDescriptorLoadsTest10.ll b/lgc/test/scalarizationOfDescriptorLoadsTest10.ll new file mode 100644 index 0000000000..7419baaa97 --- /dev/null +++ b/lgc/test/scalarizationOfDescriptorLoadsTest10.ll @@ -0,0 +1,152 @@ +; NOTE: Assertions have been autogenerated by tool/update_llpc_test_checks.py UTC_ARGS: --tool lgc +; RUN: lgc -mcpu=gfx1010 -print-after=lgc-builder-replayer -o - %s 2>&1 | FileCheck --check-prefixes=CHECK %s +; ModuleID = 'lgcPipeline' +source_filename = "llpc_fragment_7" +target datalayout = "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-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-p32:32:32" +target triple = "amdgcn--amdpal" + +; Function Attrs: nounwind +define dllexport spir_func void @lgc.shader.FS.main() local_unnamed_addr #0 !spirv.ExecutionModel !8 !lgc.shaderstage !9 { +.entry: + %0 = call i32 (...) @lgc.create.read.generic.input.i32(i32 3, i32 0, i32 0, i32 0, i32 17, i32 poison) + %1 = call ptr addrspace(4) (...) @lgc.create.get.desc.ptr.p4(i32 1, i32 1, i64 0, i32 7) + %2 = call ptr addrspace(4) (...) @lgc.create.get.desc.ptr.p4(i32 2, i32 2, i64 0, i32 7) + br label %loop + +loop: + %phi.ind = phi i32 [ 0, %.entry ], [ %ind, %loop.latch ] + %cond1 = icmp ne i32 %phi.ind, 1000 + br i1 %cond1, label %bb1, label %bb2 + +bb1: + %a = call i32 (...) @lgc.create.get.desc.stride.i32(i32 1, i32 1, i64 0, i32 7) + br label %loop.latch + +bb2: + %b = call i32 (...) @lgc.create.get.desc.stride.i32(i32 2, i32 2, i64 0, i32 7) + br label %loop.latch + +loop.latch: + %phi = phi i32 [ %a, %bb1 ], [ %b, %bb2 ] + %3 = mul i32 %phi.ind, %phi + %4 = sext i32 %3 to i64 + %5 = getelementptr i8, ptr addrspace(4) %1, i64 %4 + %6 = mul i32 %phi.ind, %phi + %7 = sext i32 %6 to i64 + %8 = getelementptr i8, ptr addrspace(4) %2, i64 %7 + %9 = load <4 x i32>, ptr addrspace(4) %8, align 16, !invariant.load !10 + %10 = load <8 x i32>, ptr addrspace(4) %5, align 32, !invariant.load !10 + %11 = call reassoc nnan nsz arcp contract afn <4 x float> (...) @lgc.create.image.sample.v4f32(i32 1, i32 24, <8 x i32> %10, <4 x i32> %9, i32 1, <2 x float> zeroinitializer) + call void (...) @lgc.create.write.generic.output(<4 x float> %11, i32 0, i32 0, i32 0, i32 0, i32 0, i32 poison) + %ind = add i32 %phi.ind, 1 + %cond2 = icmp ne i32 %ind, 1000 + br i1 %cond2, label %loop, label %exit + +exit: + ret void +} + +declare spir_func void @spirv.NonUniform.i32(i32) local_unnamed_addr + +; Function Attrs: nounwind memory(none) +declare !lgc.create.opcode !11 ptr addrspace(4) @lgc.create.get.desc.ptr.p4(...) local_unnamed_addr #1 + +; Function Attrs: nounwind memory(none) +declare !lgc.create.opcode !12 i32 @lgc.create.get.desc.stride.i32(...) local_unnamed_addr #1 + +declare spir_func void @"spirv.NonUniform.s[s[p4,i32,i32,i32],s[p4,i32,i32]]"({ { ptr addrspace(4), i32, i32, i32 }, { ptr addrspace(4), i32, i32 } }) local_unnamed_addr + +declare spir_func void @"spirv.NonUniform.s[a3v8i32,s[v4i32,i32]]"({ [3 x <8 x i32>], { <4 x i32>, i32 } }) local_unnamed_addr + +; Function Attrs: nounwind willreturn memory(read) +declare !lgc.create.opcode !13 <4 x float> @lgc.create.image.sample.v4f32(...) local_unnamed_addr #2 + +; Function Attrs: nounwind willreturn memory(read) +declare !lgc.create.opcode !14 i32 @lgc.create.read.generic.input.i32(...) local_unnamed_addr #2 + +; Function Attrs: nounwind +declare !lgc.create.opcode !15 void @lgc.create.write.generic.output(...) local_unnamed_addr #3 + +attributes #0 = { nounwind "denormal-fp-math-f32"="preserve-sign" } +attributes #1 = { nounwind memory(none) } +attributes #2 = { nounwind willreturn memory(read) } +attributes #3 = { nounwind } + +!lgc.client = !{!0} +!lgc.unlinked = !{!1} +!lgc.options = !{!2} +!lgc.options.FS = !{!3} +!lgc.user.data.nodes = !{!4, !5} +!lgc.color.export.formats = !{!6} +!amdgpu.pal.metadata.msgpack = !{!7} + +!0 = !{!"Vulkan"} +!1 = !{i32 1} +!2 = !{i32 -158725823, i32 1419665388, i32 -1015833383, i32 -491143713, i32 1, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 1, i32 256, i32 256, i32 2, i32 1} +!3 = !{i32 -1822594139, i32 1920663194, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 64, i32 0, i32 0, i32 3, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 20, i32 1800, i32 0, i32 0, i32 1} +!4 = !{!"DescriptorTableVaPtr", i32 7, i32 64, i32 0, i32 1, i32 1} +!5 = !{!"DescriptorCombinedTexture", i32 3, i32 64, i32 0, i32 192, i64 0, i32 7, i32 12} +!6 = !{i32 14, i32 7, i32 0, i32 0, i32 15} +!7 = !{!"\82\B0amdpal.pipelines\91\83\B0.spill_threshold\CD\FF\FF\B0.user_data_limit\00\AF.xgl_cache_info\82\B3.128_bit_cache_hash\92\CF\E8\D2\98>j\B9B\94\CF2\DEF\BF\9Fx\BC1\AD.llpc_version\A470.1\AEamdpal.version\92\03\00"} +!8 = !{i32 4} +!9 = !{i32 6} +!10 = !{} +!11 = !{i32 56} +!12 = !{i32 55} +!13 = !{i32 61} +!14 = !{i32 71} +!15 = !{i32 74} + +; CHECK-LABEL: @lgc.shader.FS.main( +; CHECK-NEXT: .entry: +; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.amdgcn.s.getpc() +; CHECK-NEXT: [[TMP1:%.*]] = bitcast i64 [[TMP0]] to <2 x i32> +; CHECK-NEXT: [[TMP2:%.*]] = call i64 @llvm.amdgcn.s.getpc() +; CHECK-NEXT: [[TMP3:%.*]] = bitcast i64 [[TMP2]] to <2 x i32> +; CHECK-NEXT: [[TMP4:%.*]] = call i32 (...) @lgc.input.import.interpolated.i32(i1 false, i32 3, i32 0, i32 0, i32 poison, i32 1, i32 poison) +; CHECK-NEXT: [[TMP5:%.*]] = call i32 @lgc.load.user.data.i32(i32 0) +; CHECK-NEXT: [[TMP6:%.*]] = insertelement <2 x i32> [[TMP3]], i32 [[TMP5]], i64 0 +; CHECK-NEXT: [[TMP7:%.*]] = bitcast <2 x i32> [[TMP6]] to i64 +; CHECK-NEXT: [[TMP8:%.*]] = inttoptr i64 [[TMP7]] to ptr addrspace(4) +; CHECK-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP8]], i32 0 +; CHECK-NEXT: [[TMP10:%.*]] = call i32 @lgc.load.user.data.i32(i32 0) +; CHECK-NEXT: [[TMP11:%.*]] = insertelement <2 x i32> [[TMP1]], i32 [[TMP10]], i64 0 +; CHECK-NEXT: [[TMP12:%.*]] = bitcast <2 x i32> [[TMP11]] to i64 +; CHECK-NEXT: [[TMP13:%.*]] = inttoptr i64 [[TMP12]] to ptr addrspace(4) +; CHECK-NEXT: [[TMP14:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP13]], i32 32 +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: [[PHI_IND:%.*]] = phi i32 [ 0, [[DOTENTRY:%.*]] ], [ [[IND:%.*]], [[LOOP_LATCH:%.*]] ] +; CHECK-NEXT: [[COND1:%.*]] = icmp ne i32 [[PHI_IND]], 1000 +; CHECK-NEXT: br i1 [[COND1]], label [[BB1:%.*]], label [[BB2:%.*]] +; CHECK: bb1: +; CHECK-NEXT: br label [[LOOP_LATCH]] +; CHECK: bb2: +; CHECK-NEXT: br label [[LOOP_LATCH]] +; CHECK: loop.latch: +; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 48, [[BB1]] ], [ 48, [[BB2]] ] +; CHECK-NEXT: [[TMP15:%.*]] = mul i32 [[PHI_IND]], [[PHI]] +; CHECK-NEXT: [[TMP16:%.*]] = sext i32 [[TMP15]] to i64 +; CHECK-NEXT: [[TMP17:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP9]], i64 [[TMP16]] +; CHECK-NEXT: [[TMP18:%.*]] = mul i32 [[PHI_IND]], [[PHI]] +; CHECK-NEXT: [[TMP19:%.*]] = sext i32 [[TMP18]] to i64 +; CHECK-NEXT: [[TMP20:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP14]], i64 [[TMP19]] +; CHECK-NEXT: [[TMP21:%.*]] = load <4 x i32>, ptr addrspace(4) [[TMP20]], align 16, !invariant.load !10 +; CHECK-NEXT: [[TMP22:%.*]] = load <8 x i32>, ptr addrspace(4) [[TMP17]], align 32, !invariant.load !10 +; CHECK-NEXT: [[TMP23:%.*]] = call i32 @llvm.amdgcn.waterfall.begin.i32(i32 0, i32 [[TMP15]]) +; CHECK-NEXT: [[TMP24:%.*]] = call i32 @llvm.amdgcn.waterfall.readfirstlane.i32.i32(i32 [[TMP23]], i32 [[TMP15]]) +; CHECK-NEXT: [[TMP25:%.*]] = sext i32 [[TMP24]] to i64 +; CHECK-NEXT: [[TMP26:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP9]], i64 [[TMP25]] +; CHECK-NEXT: [[TMP27:%.*]] = load <8 x i32>, ptr addrspace(4) [[TMP26]], align 32, !invariant.load !10 +; CHECK-NEXT: [[TMP28:%.*]] = sext i32 [[TMP24]] to i64 +; CHECK-NEXT: [[TMP29:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP14]], i64 [[TMP28]] +; CHECK-NEXT: [[TMP30:%.*]] = load <4 x i32>, ptr addrspace(4) [[TMP29]], align 16, !invariant.load !10 +; CHECK-NEXT: [[TMP31:%.*]] = call reassoc nnan nsz arcp contract afn <4 x float> @llvm.amdgcn.image.sample.2d.v4f32.f32(i32 15, float 0.000000e+00, float 0.000000e+00, <8 x i32> [[TMP27]], <4 x i32> [[TMP30]], i1 false, i32 0, i32 0) +; CHECK-NEXT: [[TMP32:%.*]] = call reassoc nnan nsz arcp contract afn <4 x float> @llvm.amdgcn.waterfall.end.v4f32(i32 [[TMP23]], <4 x float> [[TMP31]]) +; CHECK-NEXT: call void @lgc.output.export.generic.i32.i32.v4f32(i32 0, i32 0, <4 x float> [[TMP32]]) #[[ATTR5:[0-9]+]] +; CHECK-NEXT: [[IND]] = add i32 [[PHI_IND]], 1 +; CHECK-NEXT: [[COND2:%.*]] = icmp ne i32 [[IND]], 1000 +; CHECK-NEXT: br i1 [[COND2]], label [[LOOP]], label [[EXIT:%.*]] +; CHECK: exit: +; CHECK-NEXT: ret void +; diff --git a/lgc/test/scalarizationOfDescriptorLoadsTest11.ll b/lgc/test/scalarizationOfDescriptorLoadsTest11.ll new file mode 100644 index 0000000000..3929faae2c --- /dev/null +++ b/lgc/test/scalarizationOfDescriptorLoadsTest11.ll @@ -0,0 +1,149 @@ +; NOTE: Assertions have been autogenerated by tool/update_llpc_test_checks.py UTC_ARGS: --tool lgc +; RUN: lgc -mcpu=gfx1010 -print-after=lgc-builder-replayer -o - %s 2>&1 | FileCheck --check-prefixes=CHECK %s +; ModuleID = 'lgcPipeline' +source_filename = "llpc_fragment_7" +target datalayout = "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-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-p32:32:32" +target triple = "amdgcn--amdpal" + +; Function Attrs: nounwind +define dllexport spir_func void @lgc.shader.FS.main() local_unnamed_addr #0 !spirv.ExecutionModel !8 !lgc.shaderstage !9 { +.entry: + %0 = call i32 (...) @lgc.create.read.generic.input.i32(i32 3, i32 0, i32 0, i32 0, i32 17, i32 poison) + %1 = call ptr addrspace(4) (...) @lgc.create.get.desc.ptr.p4(i32 1, i32 1, i64 0, i32 7) + %2 = call ptr addrspace(4) (...) @lgc.create.get.desc.ptr.p4(i32 2, i32 2, i64 0, i32 7) + br label %loop + +loop: + %phi.ind = phi i32 [ 0, %.entry ], [ %ind, %loop.latch ] + %cond1 = icmp ne i32 %phi.ind, 1000 + br i1 %cond1, label %bb1, label %bb2 + +bb1: + %a = call i32 (...) @lgc.create.get.desc.stride.i32(i32 1, i32 1, i64 0, i32 7) + %3 = mul i32 %0, %a + %4 = sext i32 %3 to i64 + %5 = getelementptr i8, ptr addrspace(4) %1, i64 %4 + br label %loop.latch + +bb2: + %b = call i32 (...) @lgc.create.get.desc.stride.i32(i32 2, i32 2, i64 0, i32 7) + %6 = mul i32 %0, %b + %7 = sext i32 %6 to i64 + %8 = getelementptr i8, ptr addrspace(4) %2, i64 %7 + br label %loop.latch + +loop.latch: + %phi = phi ptr addrspace(4) [ %5, %bb1 ], [ %8, %bb2 ] + %9 = load <4 x i32>, ptr addrspace(4) %phi, align 16, !invariant.load !10 + %10 = load <8 x i32>, ptr addrspace(4) %phi, align 32, !invariant.load !10 + %11 = call reassoc nnan nsz arcp contract afn <4 x float> (...) @lgc.create.image.sample.v4f32(i32 1, i32 24, <8 x i32> %10, <4 x i32> %9, i32 1, <2 x float> zeroinitializer) + call void (...) @lgc.create.write.generic.output(<4 x float> %11, i32 0, i32 0, i32 0, i32 0, i32 0, i32 poison) + %ind = add i32 %phi.ind, 1 + %cond2 = icmp ne i32 %ind, 1000 + br i1 %cond2, label %loop, label %exit + +exit: + ret void +} + +declare spir_func void @spirv.NonUniform.i32(i32) local_unnamed_addr + +; Function Attrs: nounwind memory(none) +declare !lgc.create.opcode !11 ptr addrspace(4) @lgc.create.get.desc.ptr.p4(...) local_unnamed_addr #1 + +; Function Attrs: nounwind memory(none) +declare !lgc.create.opcode !12 i32 @lgc.create.get.desc.stride.i32(...) local_unnamed_addr #1 + +declare spir_func void @"spirv.NonUniform.s[s[p4,i32,i32,i32],s[p4,i32,i32]]"({ { ptr addrspace(4), i32, i32, i32 }, { ptr addrspace(4), i32, i32 } }) local_unnamed_addr + +declare spir_func void @"spirv.NonUniform.s[a3v8i32,s[v4i32,i32]]"({ [3 x <8 x i32>], { <4 x i32>, i32 } }) local_unnamed_addr + +; Function Attrs: nounwind willreturn memory(read) +declare !lgc.create.opcode !13 <4 x float> @lgc.create.image.sample.v4f32(...) local_unnamed_addr #2 + +; Function Attrs: nounwind willreturn memory(read) +declare !lgc.create.opcode !14 i32 @lgc.create.read.generic.input.i32(...) local_unnamed_addr #2 + +; Function Attrs: nounwind +declare !lgc.create.opcode !15 void @lgc.create.write.generic.output(...) local_unnamed_addr #3 + +attributes #0 = { nounwind "denormal-fp-math-f32"="preserve-sign" } +attributes #1 = { nounwind memory(none) } +attributes #2 = { nounwind willreturn memory(read) } +attributes #3 = { nounwind } + +!lgc.client = !{!0} +!lgc.unlinked = !{!1} +!lgc.options = !{!2} +!lgc.options.FS = !{!3} +!lgc.user.data.nodes = !{!4, !5} +!lgc.color.export.formats = !{!6} +!amdgpu.pal.metadata.msgpack = !{!7} + +!0 = !{!"Vulkan"} +!1 = !{i32 1} +!2 = !{i32 -158725823, i32 1419665388, i32 -1015833383, i32 -491143713, i32 1, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 1, i32 256, i32 256, i32 2, i32 1} +!3 = !{i32 -1822594139, i32 1920663194, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 64, i32 0, i32 0, i32 3, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 20, i32 1800, i32 0, i32 0, i32 1} +!4 = !{!"DescriptorTableVaPtr", i32 7, i32 64, i32 0, i32 1, i32 1} +!5 = !{!"DescriptorCombinedTexture", i32 3, i32 64, i32 0, i32 192, i64 0, i32 7, i32 12} +!6 = !{i32 14, i32 7, i32 0, i32 0, i32 15} +!7 = !{!"\82\B0amdpal.pipelines\91\83\B0.spill_threshold\CD\FF\FF\B0.user_data_limit\00\AF.xgl_cache_info\82\B3.128_bit_cache_hash\92\CF\E8\D2\98>j\B9B\94\CF2\DEF\BF\9Fx\BC1\AD.llpc_version\A470.1\AEamdpal.version\92\03\00"} +!8 = !{i32 4} +!9 = !{i32 6} +!10 = !{} +!11 = !{i32 56} +!12 = !{i32 55} +!13 = !{i32 61} +!14 = !{i32 71} +!15 = !{i32 74} +; CHECK-LABEL: @lgc.shader.FS.main( +; CHECK-NEXT: .entry: +; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.amdgcn.s.getpc() +; CHECK-NEXT: [[TMP1:%.*]] = bitcast i64 [[TMP0]] to <2 x i32> +; CHECK-NEXT: [[TMP2:%.*]] = call i64 @llvm.amdgcn.s.getpc() +; CHECK-NEXT: [[TMP3:%.*]] = bitcast i64 [[TMP2]] to <2 x i32> +; CHECK-NEXT: [[TMP4:%.*]] = call i32 (...) @lgc.input.import.interpolated.i32(i1 false, i32 3, i32 0, i32 0, i32 poison, i32 1, i32 poison) +; CHECK-NEXT: [[TMP5:%.*]] = call i32 @lgc.load.user.data.i32(i32 0) +; CHECK-NEXT: [[TMP6:%.*]] = insertelement <2 x i32> [[TMP3]], i32 [[TMP5]], i64 0 +; CHECK-NEXT: [[TMP7:%.*]] = bitcast <2 x i32> [[TMP6]] to i64 +; CHECK-NEXT: [[TMP8:%.*]] = inttoptr i64 [[TMP7]] to ptr addrspace(4) +; CHECK-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP8]], i32 0 +; CHECK-NEXT: [[TMP10:%.*]] = call i32 @lgc.load.user.data.i32(i32 0) +; CHECK-NEXT: [[TMP11:%.*]] = insertelement <2 x i32> [[TMP1]], i32 [[TMP10]], i64 0 +; CHECK-NEXT: [[TMP12:%.*]] = bitcast <2 x i32> [[TMP11]] to i64 +; CHECK-NEXT: [[TMP13:%.*]] = inttoptr i64 [[TMP12]] to ptr addrspace(4) +; CHECK-NEXT: [[TMP14:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP13]], i32 32 +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: [[PHI_IND:%.*]] = phi i32 [ 0, [[DOTENTRY:%.*]] ], [ [[IND:%.*]], [[LOOP_LATCH:%.*]] ] +; CHECK-NEXT: [[COND1:%.*]] = icmp ne i32 [[PHI_IND]], 1000 +; CHECK-NEXT: br i1 [[COND1]], label [[BB1:%.*]], label [[BB2:%.*]] +; CHECK: bb1: +; CHECK-NEXT: [[TMP15:%.*]] = mul i32 [[TMP4]], 48 +; CHECK-NEXT: [[TMP16:%.*]] = sext i32 [[TMP15]] to i64 +; CHECK-NEXT: [[TMP17:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP9]], i64 [[TMP16]] +; CHECK-NEXT: br label [[LOOP_LATCH]] +; CHECK: bb2: +; CHECK-NEXT: [[TMP18:%.*]] = mul i32 [[TMP4]], 48 +; CHECK-NEXT: [[TMP19:%.*]] = sext i32 [[TMP18]] to i64 +; CHECK-NEXT: [[TMP20:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP14]], i64 [[TMP19]] +; CHECK-NEXT: br label [[LOOP_LATCH]] +; CHECK: loop.latch: +; CHECK-NEXT: [[PHI:%.*]] = phi ptr addrspace(4) [ [[TMP17]], [[BB1]] ], [ [[TMP20]], [[BB2]] ] +; CHECK-NEXT: [[TMP21:%.*]] = load <4 x i32>, ptr addrspace(4) [[PHI]], align 16, !invariant.load !10 +; CHECK-NEXT: [[TMP22:%.*]] = load <8 x i32>, ptr addrspace(4) [[PHI]], align 32, !invariant.load !10 +; CHECK-NEXT: [[TMP23:%.*]] = call i32 @llvm.amdgcn.waterfall.begin.v8i32(i32 0, <8 x i32> [[TMP22]]) +; CHECK-NEXT: [[TMP24:%.*]] = call i32 @llvm.amdgcn.waterfall.begin.v4i32(i32 [[TMP23]], <4 x i32> [[TMP21]]) +; CHECK-NEXT: [[TMP25:%.*]] = call <8 x i32> @llvm.amdgcn.waterfall.readfirstlane.v8i32.v8i32(i32 [[TMP24]], <8 x i32> [[TMP22]]) +; CHECK-NEXT: [[TMP26:%.*]] = load <8 x i32>, ptr addrspace(4) [[PHI]], align 32, !invariant.load !10 +; CHECK-NEXT: [[TMP27:%.*]] = call <4 x i32> @llvm.amdgcn.waterfall.readfirstlane.v4i32.v4i32(i32 [[TMP24]], <4 x i32> [[TMP21]]) +; CHECK-NEXT: [[TMP28:%.*]] = load <4 x i32>, ptr addrspace(4) [[PHI]], align 16, !invariant.load !10 +; CHECK-NEXT: [[TMP29:%.*]] = call reassoc nnan nsz arcp contract afn <4 x float> @llvm.amdgcn.image.sample.2d.v4f32.f32(i32 15, float 0.000000e+00, float 0.000000e+00, <8 x i32> [[TMP25]], <4 x i32> [[TMP27]], i1 false, i32 0, i32 0) +; CHECK-NEXT: [[TMP30:%.*]] = call reassoc nnan nsz arcp contract afn <4 x float> @llvm.amdgcn.waterfall.end.v4f32(i32 [[TMP24]], <4 x float> [[TMP29]]) +; CHECK-NEXT: call void @lgc.output.export.generic.i32.i32.v4f32(i32 0, i32 0, <4 x float> [[TMP30]]) #[[ATTR5:[0-9]+]] +; CHECK-NEXT: [[IND]] = add i32 [[PHI_IND]], 1 +; CHECK-NEXT: [[COND2:%.*]] = icmp ne i32 [[IND]], 1000 +; CHECK-NEXT: br i1 [[COND2]], label [[LOOP]], label [[EXIT:%.*]] +; CHECK: exit: +; CHECK-NEXT: ret void +; diff --git a/lgc/test/scalarizationOfDescriptorLoadsTest12.ll b/lgc/test/scalarizationOfDescriptorLoadsTest12.ll new file mode 100644 index 0000000000..88e2c0f970 --- /dev/null +++ b/lgc/test/scalarizationOfDescriptorLoadsTest12.ll @@ -0,0 +1,137 @@ +; NOTE: Assertions have been autogenerated by tool/update_llpc_test_checks.py UTC_ARGS: --tool lgc +; RUN: lgc -mcpu=gfx1010 -print-after=lgc-builder-replayer -o - %s 2>&1 | FileCheck --check-prefixes=CHECK %s +; ModuleID = 'lgcPipeline' +source_filename = "llpc_fragment_7" +target datalayout = "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-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-p32:32:32" +target triple = "amdgcn--amdpal" + +; Function Attrs: nounwind +define dllexport spir_func void @lgc.shader.FS.main() local_unnamed_addr #0 !spirv.ExecutionModel !8 !lgc.shaderstage !9 { +.entry: + %0 = call i32 (...) @lgc.create.read.generic.input.i32(i32 3, i32 0, i32 0, i32 0, i32 17, i32 poison) + %1 = call ptr addrspace(4) (...) @lgc.create.get.desc.ptr.p4(i32 1, i32 1, i64 0, i32 7) + %2 = call ptr addrspace(4) (...) @lgc.create.get.desc.ptr.p4(i32 2, i32 2, i64 0, i32 7) + br label %loop + +loop: + %phi.ind = phi i32 [ 0, %.entry ], [ %ind, %loop ] + %phi.img = phi <4 x float> [ , %.entry ], [ %11, %loop ] + %a = call i32 (...) @lgc.create.get.desc.stride.i32(i32 1, i32 1, i64 0, i32 7) + %b = call i32 (...) @lgc.create.get.desc.stride.i32(i32 2, i32 2, i64 0, i32 7) + %3 = mul i32 %phi.ind, %a + %4 = sext i32 %3 to i64 + %5 = getelementptr i8, ptr addrspace(4) %1, i64 %4 + %6 = mul i32 %phi.ind, %b + %7 = sext i32 %6 to i64 + %8 = getelementptr i8, ptr addrspace(4) %2, i64 %7 + %9 = load <4 x i32>, ptr addrspace(4) %8, align 16, !invariant.load !10 + %10 = load <8 x i32>, ptr addrspace(4) %5, align 32, !invariant.load !10 + %11 = call reassoc nnan nsz arcp contract afn <4 x float> (...) @lgc.create.image.sample.v4f32(i32 1, i32 24, <8 x i32> %10, <4 x i32> %9, i32 1, <2 x float> zeroinitializer) + %12 = fadd <4 x float> %phi.img, + %ind = add i32 %phi.ind, 1 + %cond = icmp ne i32 %ind, 1000 + br i1 %cond, label %loop, label %exit + +exit: + call void (...) @lgc.create.write.generic.output(<4 x float> %12, i32 0, i32 0, i32 0, i32 0, i32 0, i32 poison) + ret void +} + +declare spir_func void @spirv.NonUniform.i32(i32) local_unnamed_addr + +; Function Attrs: nounwind memory(none) +declare !lgc.create.opcode !11 ptr addrspace(4) @lgc.create.get.desc.ptr.p4(...) local_unnamed_addr #1 + +; Function Attrs: nounwind memory(none) +declare !lgc.create.opcode !12 i32 @lgc.create.get.desc.stride.i32(...) local_unnamed_addr #1 + +declare spir_func void @"spirv.NonUniform.s[s[p4,i32,i32,i32],s[p4,i32,i32]]"({ { ptr addrspace(4), i32, i32, i32 }, { ptr addrspace(4), i32, i32 } }) local_unnamed_addr + +declare spir_func void @"spirv.NonUniform.s[a3v8i32,s[v4i32,i32]]"({ [3 x <8 x i32>], { <4 x i32>, i32 } }) local_unnamed_addr + +; Function Attrs: nounwind willreturn memory(read) +declare !lgc.create.opcode !13 <4 x float> @lgc.create.image.sample.v4f32(...) local_unnamed_addr #2 + +; Function Attrs: nounwind willreturn memory(read) +declare !lgc.create.opcode !14 i32 @lgc.create.read.generic.input.i32(...) local_unnamed_addr #2 + +; Function Attrs: nounwind +declare !lgc.create.opcode !15 void @lgc.create.write.generic.output(...) local_unnamed_addr #3 + +attributes #0 = { nounwind "denormal-fp-math-f32"="preserve-sign" } +attributes #1 = { nounwind memory(none) } +attributes #2 = { nounwind willreturn memory(read) } +attributes #3 = { nounwind } + +!lgc.client = !{!0} +!lgc.unlinked = !{!1} +!lgc.options = !{!2} +!lgc.options.FS = !{!3} +!lgc.user.data.nodes = !{!4, !5} +!lgc.color.export.formats = !{!6} +!amdgpu.pal.metadata.msgpack = !{!7} + +!0 = !{!"Vulkan"} +!1 = !{i32 1} +!2 = !{i32 -158725823, i32 1419665388, i32 -1015833383, i32 -491143713, i32 1, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 1, i32 256, i32 256, i32 2, i32 1} +!3 = !{i32 -1822594139, i32 1920663194, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 64, i32 0, i32 0, i32 3, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 20, i32 1800, i32 0, i32 0, i32 1} +!4 = !{!"DescriptorTableVaPtr", i32 7, i32 64, i32 0, i32 1, i32 1} +!5 = !{!"DescriptorCombinedTexture", i32 3, i32 64, i32 0, i32 192, i64 0, i32 7, i32 12} +!6 = !{i32 14, i32 7, i32 0, i32 0, i32 15} +!7 = !{!"\82\B0amdpal.pipelines\91\83\B0.spill_threshold\CD\FF\FF\B0.user_data_limit\00\AF.xgl_cache_info\82\B3.128_bit_cache_hash\92\CF\E8\D2\98>j\B9B\94\CF2\DEF\BF\9Fx\BC1\AD.llpc_version\A470.1\AEamdpal.version\92\03\00"} +!8 = !{i32 4} +!9 = !{i32 6} +!10 = !{} +!11 = !{i32 56} +!12 = !{i32 55} +!13 = !{i32 61} +!14 = !{i32 71} +!15 = !{i32 74} + +; CHECK-LABEL: @lgc.shader.FS.main( +; CHECK-NEXT: .entry: +; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.amdgcn.s.getpc() +; CHECK-NEXT: [[TMP1:%.*]] = bitcast i64 [[TMP0]] to <2 x i32> +; CHECK-NEXT: [[TMP2:%.*]] = call i64 @llvm.amdgcn.s.getpc() +; CHECK-NEXT: [[TMP3:%.*]] = bitcast i64 [[TMP2]] to <2 x i32> +; CHECK-NEXT: [[TMP4:%.*]] = call i32 (...) @lgc.input.import.interpolated.i32(i1 false, i32 3, i32 0, i32 0, i32 poison, i32 1, i32 poison) +; CHECK-NEXT: [[TMP5:%.*]] = call i32 @lgc.load.user.data.i32(i32 0) +; CHECK-NEXT: [[TMP6:%.*]] = insertelement <2 x i32> [[TMP3]], i32 [[TMP5]], i64 0 +; CHECK-NEXT: [[TMP7:%.*]] = bitcast <2 x i32> [[TMP6]] to i64 +; CHECK-NEXT: [[TMP8:%.*]] = inttoptr i64 [[TMP7]] to ptr addrspace(4) +; CHECK-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP8]], i32 0 +; CHECK-NEXT: [[TMP10:%.*]] = call i32 @lgc.load.user.data.i32(i32 0) +; CHECK-NEXT: [[TMP11:%.*]] = insertelement <2 x i32> [[TMP1]], i32 [[TMP10]], i64 0 +; CHECK-NEXT: [[TMP12:%.*]] = bitcast <2 x i32> [[TMP11]] to i64 +; CHECK-NEXT: [[TMP13:%.*]] = inttoptr i64 [[TMP12]] to ptr addrspace(4) +; CHECK-NEXT: [[TMP14:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP13]], i32 32 +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: [[PHI_IND:%.*]] = phi i32 [ 0, [[DOTENTRY:%.*]] ], [ [[IND:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[PHI_IMG:%.*]] = phi <4 x float> [ , [[DOTENTRY]] ], [ [[TMP32:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[TMP15:%.*]] = mul i32 [[PHI_IND]], 48 +; CHECK-NEXT: [[TMP16:%.*]] = sext i32 [[TMP15]] to i64 +; CHECK-NEXT: [[TMP17:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP9]], i64 [[TMP16]] +; CHECK-NEXT: [[TMP18:%.*]] = mul i32 [[PHI_IND]], 48 +; CHECK-NEXT: [[TMP19:%.*]] = sext i32 [[TMP18]] to i64 +; CHECK-NEXT: [[TMP20:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP14]], i64 [[TMP19]] +; CHECK-NEXT: [[TMP21:%.*]] = load <4 x i32>, ptr addrspace(4) [[TMP20]], align 16, !invariant.load !10 +; CHECK-NEXT: [[TMP22:%.*]] = load <8 x i32>, ptr addrspace(4) [[TMP17]], align 32, !invariant.load !10 +; CHECK-NEXT: [[TMP23:%.*]] = call i32 @llvm.amdgcn.waterfall.begin.i32(i32 0, i32 [[TMP15]]) +; CHECK-NEXT: [[TMP24:%.*]] = call i32 @llvm.amdgcn.waterfall.readfirstlane.i32.i32(i32 [[TMP23]], i32 [[TMP15]]) +; CHECK-NEXT: [[TMP25:%.*]] = sext i32 [[TMP24]] to i64 +; CHECK-NEXT: [[TMP26:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP9]], i64 [[TMP25]] +; CHECK-NEXT: [[TMP27:%.*]] = load <8 x i32>, ptr addrspace(4) [[TMP26]], align 32, !invariant.load !10 +; CHECK-NEXT: [[TMP28:%.*]] = sext i32 [[TMP24]] to i64 +; CHECK-NEXT: [[TMP29:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP14]], i64 [[TMP28]] +; CHECK-NEXT: [[TMP30:%.*]] = load <4 x i32>, ptr addrspace(4) [[TMP29]], align 16, !invariant.load !10 +; CHECK-NEXT: [[TMP31:%.*]] = call reassoc nnan nsz arcp contract afn <4 x float> @llvm.amdgcn.image.sample.2d.v4f32.f32(i32 15, float 0.000000e+00, float 0.000000e+00, <8 x i32> [[TMP27]], <4 x i32> [[TMP30]], i1 false, i32 0, i32 0) +; CHECK-NEXT: [[TMP32]] = call reassoc nnan nsz arcp contract afn <4 x float> @llvm.amdgcn.waterfall.end.v4f32(i32 [[TMP23]], <4 x float> [[TMP31]]) +; CHECK-NEXT: [[TMP33:%.*]] = fadd <4 x float> [[PHI_IMG]], +; CHECK-NEXT: [[IND]] = add i32 [[PHI_IND]], 1 +; CHECK-NEXT: [[COND:%.*]] = icmp ne i32 [[IND]], 1000 +; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]] +; CHECK: exit: +; CHECK-NEXT: call void @lgc.output.export.generic.i32.i32.v4f32(i32 0, i32 0, <4 x float> [[TMP33]]) #[[ATTR5:[0-9]+]] +; CHECK-NEXT: ret void +; diff --git a/lgc/test/scalarizationOfDescriptorLoadsTest13.ll b/lgc/test/scalarizationOfDescriptorLoadsTest13.ll new file mode 100644 index 0000000000..70574ee31f --- /dev/null +++ b/lgc/test/scalarizationOfDescriptorLoadsTest13.ll @@ -0,0 +1,136 @@ +; NOTE: Assertions have been autogenerated by tool/update_llpc_test_checks.py UTC_ARGS: --tool lgc +; RUN: lgc -mcpu=gfx1010 -print-after=lgc-builder-replayer -o - %s 2>&1 | FileCheck --check-prefixes=CHECK %s +; ModuleID = 'lgcPipeline' +source_filename = "llpc_fragment_7" +target datalayout = "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-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-p32:32:32" +target triple = "amdgcn--amdpal" + +; Function Attrs: nounwind +define dllexport spir_func void @lgc.shader.FS.main() local_unnamed_addr #0 !spirv.ExecutionModel !8 !lgc.shaderstage !9 { +.entry: + %0 = call i32 (...) @lgc.create.read.generic.input.i32(i32 3, i32 0, i32 0, i32 0, i32 17, i32 poison) + %1 = call ptr addrspace(4) (...) @lgc.create.get.desc.ptr.p4(i32 1, i32 1, i64 0, i32 7) + %2 = call ptr addrspace(4) (...) @lgc.create.get.desc.ptr.p4(i32 2, i32 2, i64 0, i32 7) + %a = call i32 (...) @lgc.create.get.desc.stride.i32(i32 1, i32 1, i64 0, i32 7) + %3 = mul i32 %0, %a + %4 = sext i32 %3 to i64 + %5 = getelementptr i8, ptr addrspace(4) %1, i64 %4 + %l = load <8 x i32>, ptr addrspace(4) %5, align 32, !invariant.load !10 + br label %loop + +loop: + %phi.ind = phi i32 [ 0, %.entry ], [ %ind, %loop ] + %phi.load = phi <8 x i32> [ %l, %.entry ], [ %10, %loop ] + %b = call i32 (...) @lgc.create.get.desc.stride.i32(i32 2, i32 2, i64 0, i32 7) + %6 = mul i32 %phi.ind, %b + %7 = sext i32 %6 to i64 + %8 = getelementptr i8, ptr addrspace(4) %2, i64 %7 + %9 = load <4 x i32>, ptr addrspace(4) %8, align 16, !invariant.load !10 + %10 = load <8 x i32>, ptr addrspace(4) %8, align 32, !invariant.load !10 + %11 = call reassoc nnan nsz arcp contract afn <4 x float> (...) @lgc.create.image.sample.v4f32(i32 1, i32 24, <8 x i32> %phi.load, <4 x i32> %9, i32 1, <2 x float> zeroinitializer) + call void (...) @lgc.create.write.generic.output(<4 x float> %11, i32 0, i32 0, i32 0, i32 0, i32 0, i32 poison) + %ind = add i32 %phi.ind, 1 + %cond = icmp ne i32 %ind, 1000 + br i1 %cond, label %loop, label %exit + +exit: + ret void +} + +declare spir_func void @spirv.NonUniform.i32(i32) local_unnamed_addr + +; Function Attrs: nounwind memory(none) +declare !lgc.create.opcode !11 ptr addrspace(4) @lgc.create.get.desc.ptr.p4(...) local_unnamed_addr #1 + +; Function Attrs: nounwind memory(none) +declare !lgc.create.opcode !12 i32 @lgc.create.get.desc.stride.i32(...) local_unnamed_addr #1 + +declare spir_func void @"spirv.NonUniform.s[s[p4,i32,i32,i32],s[p4,i32,i32]]"({ { ptr addrspace(4), i32, i32, i32 }, { ptr addrspace(4), i32, i32 } }) local_unnamed_addr + +declare spir_func void @"spirv.NonUniform.s[a3v8i32,s[v4i32,i32]]"({ [3 x <8 x i32>], { <4 x i32>, i32 } }) local_unnamed_addr + +; Function Attrs: nounwind willreturn memory(read) +declare !lgc.create.opcode !13 <4 x float> @lgc.create.image.sample.v4f32(...) local_unnamed_addr #2 + +; Function Attrs: nounwind willreturn memory(read) +declare !lgc.create.opcode !14 i32 @lgc.create.read.generic.input.i32(...) local_unnamed_addr #2 + +; Function Attrs: nounwind +declare !lgc.create.opcode !15 void @lgc.create.write.generic.output(...) local_unnamed_addr #3 + +attributes #0 = { nounwind "denormal-fp-math-f32"="preserve-sign" } +attributes #1 = { nounwind memory(none) } +attributes #2 = { nounwind willreturn memory(read) } +attributes #3 = { nounwind } + +!lgc.client = !{!0} +!lgc.unlinked = !{!1} +!lgc.options = !{!2} +!lgc.options.FS = !{!3} +!lgc.user.data.nodes = !{!4, !5} +!lgc.color.export.formats = !{!6} +!amdgpu.pal.metadata.msgpack = !{!7} + +!0 = !{!"Vulkan"} +!1 = !{i32 1} +!2 = !{i32 -158725823, i32 1419665388, i32 -1015833383, i32 -491143713, i32 1, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 1, i32 256, i32 256, i32 2, i32 1} +!3 = !{i32 -1822594139, i32 1920663194, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 64, i32 0, i32 0, i32 3, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 20, i32 1800, i32 0, i32 0, i32 1} +!4 = !{!"DescriptorTableVaPtr", i32 7, i32 64, i32 0, i32 1, i32 1} +!5 = !{!"DescriptorCombinedTexture", i32 3, i32 64, i32 0, i32 192, i64 0, i32 7, i32 12} +!6 = !{i32 14, i32 7, i32 0, i32 0, i32 15} +!7 = !{!"\82\B0amdpal.pipelines\91\83\B0.spill_threshold\CD\FF\FF\B0.user_data_limit\00\AF.xgl_cache_info\82\B3.128_bit_cache_hash\92\CF\E8\D2\98>j\B9B\94\CF2\DEF\BF\9Fx\BC1\AD.llpc_version\A470.1\AEamdpal.version\92\03\00"} +!8 = !{i32 4} +!9 = !{i32 6} +!10 = !{} +!11 = !{i32 56} +!12 = !{i32 55} +!13 = !{i32 61} +!14 = !{i32 71} +!15 = !{i32 74} + +; CHECK-LABEL: @lgc.shader.FS.main( +; CHECK-NEXT: .entry: +; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.amdgcn.s.getpc() +; CHECK-NEXT: [[TMP1:%.*]] = bitcast i64 [[TMP0]] to <2 x i32> +; CHECK-NEXT: [[TMP2:%.*]] = call i64 @llvm.amdgcn.s.getpc() +; CHECK-NEXT: [[TMP3:%.*]] = bitcast i64 [[TMP2]] to <2 x i32> +; CHECK-NEXT: [[TMP4:%.*]] = call i32 (...) @lgc.input.import.interpolated.i32(i1 false, i32 3, i32 0, i32 0, i32 poison, i32 1, i32 poison) +; CHECK-NEXT: [[TMP5:%.*]] = call i32 @lgc.load.user.data.i32(i32 0) +; CHECK-NEXT: [[TMP6:%.*]] = insertelement <2 x i32> [[TMP3]], i32 [[TMP5]], i64 0 +; CHECK-NEXT: [[TMP7:%.*]] = bitcast <2 x i32> [[TMP6]] to i64 +; CHECK-NEXT: [[TMP8:%.*]] = inttoptr i64 [[TMP7]] to ptr addrspace(4) +; CHECK-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP8]], i32 0 +; CHECK-NEXT: [[TMP10:%.*]] = call i32 @lgc.load.user.data.i32(i32 0) +; CHECK-NEXT: [[TMP11:%.*]] = insertelement <2 x i32> [[TMP1]], i32 [[TMP10]], i64 0 +; CHECK-NEXT: [[TMP12:%.*]] = bitcast <2 x i32> [[TMP11]] to i64 +; CHECK-NEXT: [[TMP13:%.*]] = inttoptr i64 [[TMP12]] to ptr addrspace(4) +; CHECK-NEXT: [[TMP14:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP13]], i32 32 +; CHECK-NEXT: [[TMP15:%.*]] = mul i32 [[TMP4]], 48 +; CHECK-NEXT: [[TMP16:%.*]] = sext i32 [[TMP15]] to i64 +; CHECK-NEXT: [[TMP17:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP9]], i64 [[TMP16]] +; CHECK-NEXT: [[L:%.*]] = load <8 x i32>, ptr addrspace(4) [[TMP17]], align 32, !invariant.load !10 +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: [[PHI_IND:%.*]] = phi i32 [ 0, [[DOTENTRY:%.*]] ], [ [[IND:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[PHI_LOAD:%.*]] = phi <8 x i32> [ [[L]], [[DOTENTRY]] ], [ [[TMP22:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[TMP18:%.*]] = mul i32 [[PHI_IND]], 48 +; CHECK-NEXT: [[TMP19:%.*]] = sext i32 [[TMP18]] to i64 +; CHECK-NEXT: [[TMP20:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP14]], i64 [[TMP19]] +; CHECK-NEXT: [[TMP21:%.*]] = load <4 x i32>, ptr addrspace(4) [[TMP20]], align 16, !invariant.load !10 +; CHECK-NEXT: [[TMP22]] = load <8 x i32>, ptr addrspace(4) [[TMP20]], align 32, !invariant.load !10 +; CHECK-NEXT: [[TMP23:%.*]] = call i32 @llvm.amdgcn.waterfall.begin.v8i32(i32 0, <8 x i32> [[PHI_LOAD]]) +; CHECK-NEXT: [[TMP24:%.*]] = call i32 @llvm.amdgcn.waterfall.begin.i32(i32 [[TMP23]], i32 [[TMP18]]) +; CHECK-NEXT: [[TMP25:%.*]] = call <8 x i32> @llvm.amdgcn.waterfall.readfirstlane.v8i32.v8i32(i32 [[TMP24]], <8 x i32> [[PHI_LOAD]]) +; CHECK-NEXT: [[TMP26:%.*]] = call i32 @llvm.amdgcn.waterfall.readfirstlane.i32.i32(i32 [[TMP24]], i32 [[TMP18]]) +; CHECK-NEXT: [[TMP27:%.*]] = sext i32 [[TMP26]] to i64 +; CHECK-NEXT: [[TMP28:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP14]], i64 [[TMP27]] +; CHECK-NEXT: [[TMP29:%.*]] = load <4 x i32>, ptr addrspace(4) [[TMP28]], align 16, !invariant.load !10 +; CHECK-NEXT: [[TMP30:%.*]] = call reassoc nnan nsz arcp contract afn <4 x float> @llvm.amdgcn.image.sample.2d.v4f32.f32(i32 15, float 0.000000e+00, float 0.000000e+00, <8 x i32> [[TMP25]], <4 x i32> [[TMP29]], i1 false, i32 0, i32 0) +; CHECK-NEXT: [[TMP31:%.*]] = call reassoc nnan nsz arcp contract afn <4 x float> @llvm.amdgcn.waterfall.end.v4f32(i32 [[TMP24]], <4 x float> [[TMP30]]) +; CHECK-NEXT: call void @lgc.output.export.generic.i32.i32.v4f32(i32 0, i32 0, <4 x float> [[TMP31]]) #[[ATTR5:[0-9]+]] +; CHECK-NEXT: [[IND]] = add i32 [[PHI_IND]], 1 +; CHECK-NEXT: [[COND:%.*]] = icmp ne i32 [[IND]], 1000 +; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]] +; CHECK: exit: +; CHECK-NEXT: ret void +; diff --git a/lgc/test/scalarizationOfDescriptorLoadsTest14.ll b/lgc/test/scalarizationOfDescriptorLoadsTest14.ll new file mode 100644 index 0000000000..d7a5bfad5c --- /dev/null +++ b/lgc/test/scalarizationOfDescriptorLoadsTest14.ll @@ -0,0 +1,144 @@ +; NOTE: Assertions have been autogenerated by tool/update_llpc_test_checks.py UTC_ARGS: --tool lgc +; RUN: lgc -mcpu=gfx1010 -print-after=lgc-builder-replayer -o - %s 2>&1 | FileCheck --check-prefixes=CHECK %s +; ModuleID = 'lgcPipeline' +source_filename = "llpc_fragment_7" +target datalayout = "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-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-p32:32:32" +target triple = "amdgcn--amdpal" + +; Function Attrs: nounwind +define dllexport spir_func void @lgc.shader.FS.main() local_unnamed_addr #0 !spirv.ExecutionModel !8 !lgc.shaderstage !9 { +.entry: + %0 = call i32 (...) @lgc.create.read.generic.input.i32(i32 3, i32 0, i32 0, i32 0, i32 17, i32 poison) + %1 = call ptr addrspace(4) (...) @lgc.create.get.desc.ptr.p4(i32 1, i32 1, i64 0, i32 7) + %2 = call ptr addrspace(4) (...) @lgc.create.get.desc.ptr.p4(i32 2, i32 2, i64 0, i32 7) + br label %loop + +loop: + %phi.ind = phi i32 [ 0, %.entry ], [ %ind, %loop ] + %phi.img = phi <4 x float> [ , %.entry ], [ %11, %loop ] + %a = call i32 (...) @lgc.create.get.desc.stride.i32(i32 1, i32 1, i64 0, i32 7) + %b = call i32 (...) @lgc.create.get.desc.stride.i32(i32 2, i32 2, i64 0, i32 7) + %3 = mul i32 %phi.ind, %a + %4 = sext i32 %3 to i64 + %5 = getelementptr i8, ptr addrspace(4) %1, i64 %4 + %6 = mul i32 %phi.ind, %b + %7 = sext i32 %6 to i64 + %8 = getelementptr i8, ptr addrspace(4) %2, i64 %7 + %9 = load <4 x i32>, ptr addrspace(4) %8, align 16, !invariant.load !10 + %10 = load <8 x i32>, ptr addrspace(4) %5, align 32, !invariant.load !10 + %11 = call reassoc nnan nsz arcp contract afn <4 x float> (...) @lgc.create.image.sample.v4f32(i32 1, i32 24, <8 x i32> %10, <4 x i32> %9, i32 1, <2 x float> zeroinitializer) + %12 = fadd <4 x float> %phi.img, + %ind = add i32 %phi.ind, 1 + %cond = icmp ne i32 %ind, 1000 + br i1 %cond, label %loop, label %exit + +exit: + call void (...) @lgc.create.image.store(<4 x float> %12, i32 0, i32 8, <4 x i32> %9, i32 1) + ret void +} + +declare spir_func void @spirv.NonUniform.i32(i32) local_unnamed_addr + +; Function Attrs: nounwind memory(none) +declare !lgc.create.opcode !11 ptr addrspace(4) @lgc.create.get.desc.ptr.p4(...) local_unnamed_addr #1 + +; Function Attrs: nounwind memory(none) +declare !lgc.create.opcode !12 i32 @lgc.create.get.desc.stride.i32(...) local_unnamed_addr #1 + +declare spir_func void @"spirv.NonUniform.s[s[p4,i32,i32,i32],s[p4,i32,i32]]"({ { ptr addrspace(4), i32, i32, i32 }, { ptr addrspace(4), i32, i32 } }) local_unnamed_addr + +declare spir_func void @"spirv.NonUniform.s[a3v8i32,s[v4i32,i32]]"({ [3 x <8 x i32>], { <4 x i32>, i32 } }) local_unnamed_addr + +; Function Attrs: nounwind willreturn memory(read) +declare !lgc.create.opcode !13 <4 x float> @lgc.create.image.sample.v4f32(...) local_unnamed_addr #2 + +; Function Attrs: nounwind willreturn memory(read) +declare !lgc.create.opcode !14 i32 @lgc.create.read.generic.input.i32(...) local_unnamed_addr #2 + +; Function Attrs: nounwind memory(write) +declare void @lgc.create.image.store(...) local_unnamed_addr #4 + +attributes #0 = { nounwind "denormal-fp-math-f32"="preserve-sign" } +attributes #1 = { nounwind memory(none) } +attributes #2 = { nounwind willreturn memory(read) } +attributes #3 = { nounwind } +attributes #4 = { nounwind memory(write) } + +!lgc.client = !{!0} +!lgc.unlinked = !{!1} +!lgc.options = !{!2} +!lgc.options.FS = !{!3} +!lgc.user.data.nodes = !{!4, !5} +!lgc.color.export.formats = !{!6} +!amdgpu.pal.metadata.msgpack = !{!7} + +!0 = !{!"Vulkan"} +!1 = !{i32 1} +!2 = !{i32 -158725823, i32 1419665388, i32 -1015833383, i32 -491143713, i32 1, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 1, i32 256, i32 256, i32 2, i32 1} +!3 = !{i32 -1822594139, i32 1920663194, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 64, i32 0, i32 0, i32 3, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 20, i32 1800, i32 0, i32 0, i32 1} +!4 = !{!"DescriptorTableVaPtr", i32 7, i32 64, i32 0, i32 1, i32 1} +!5 = !{!"DescriptorCombinedTexture", i32 3, i32 64, i32 0, i32 192, i64 0, i32 7, i32 12} +!6 = !{i32 14, i32 7, i32 0, i32 0, i32 15} +!7 = !{!"\82\B0amdpal.pipelines\91\83\B0.spill_threshold\CD\FF\FF\B0.user_data_limit\00\AF.xgl_cache_info\82\B3.128_bit_cache_hash\92\CF\E8\D2\98>j\B9B\94\CF2\DEF\BF\9Fx\BC1\AD.llpc_version\A470.1\AEamdpal.version\92\03\00"} +!8 = !{i32 4} +!9 = !{i32 6} +!10 = !{} +!11 = !{i32 56} +!12 = !{i32 55} +!13 = !{i32 61} +!14 = !{i32 71} +!15 = !{i32 74} + +; CHECK-LABEL: @lgc.shader.FS.main( +; CHECK-NEXT: .entry: +; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.amdgcn.s.getpc() +; CHECK-NEXT: [[TMP1:%.*]] = bitcast i64 [[TMP0]] to <2 x i32> +; CHECK-NEXT: [[TMP2:%.*]] = call i64 @llvm.amdgcn.s.getpc() +; CHECK-NEXT: [[TMP3:%.*]] = bitcast i64 [[TMP2]] to <2 x i32> +; CHECK-NEXT: [[TMP4:%.*]] = call i32 (...) @lgc.input.import.interpolated.i32(i1 false, i32 3, i32 0, i32 0, i32 poison, i32 1, i32 poison) +; CHECK-NEXT: [[TMP5:%.*]] = call i32 @lgc.load.user.data.i32(i32 0) +; CHECK-NEXT: [[TMP6:%.*]] = insertelement <2 x i32> [[TMP3]], i32 [[TMP5]], i64 0 +; CHECK-NEXT: [[TMP7:%.*]] = bitcast <2 x i32> [[TMP6]] to i64 +; CHECK-NEXT: [[TMP8:%.*]] = inttoptr i64 [[TMP7]] to ptr addrspace(4) +; CHECK-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP8]], i32 0 +; CHECK-NEXT: [[TMP10:%.*]] = call i32 @lgc.load.user.data.i32(i32 0) +; CHECK-NEXT: [[TMP11:%.*]] = insertelement <2 x i32> [[TMP1]], i32 [[TMP10]], i64 0 +; CHECK-NEXT: [[TMP12:%.*]] = bitcast <2 x i32> [[TMP11]] to i64 +; CHECK-NEXT: [[TMP13:%.*]] = inttoptr i64 [[TMP12]] to ptr addrspace(4) +; CHECK-NEXT: [[TMP14:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP13]], i32 32 +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: [[PHI_IND:%.*]] = phi i32 [ 0, [[DOTENTRY:%.*]] ], [ [[IND:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[PHI_IMG:%.*]] = phi <4 x float> [ , [[DOTENTRY]] ], [ [[TMP32:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[TMP15:%.*]] = mul i32 [[PHI_IND]], 48 +; CHECK-NEXT: [[TMP16:%.*]] = sext i32 [[TMP15]] to i64 +; CHECK-NEXT: [[TMP17:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP9]], i64 [[TMP16]] +; CHECK-NEXT: [[TMP18:%.*]] = mul i32 [[PHI_IND]], 48 +; CHECK-NEXT: [[TMP19:%.*]] = sext i32 [[TMP18]] to i64 +; CHECK-NEXT: [[TMP20:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP14]], i64 [[TMP19]] +; CHECK-NEXT: [[TMP21:%.*]] = load <4 x i32>, ptr addrspace(4) [[TMP20]], align 16, !invariant.load !10 +; CHECK-NEXT: [[TMP22:%.*]] = load <8 x i32>, ptr addrspace(4) [[TMP17]], align 32, !invariant.load !10 +; CHECK-NEXT: [[TMP23:%.*]] = call i32 @llvm.amdgcn.waterfall.begin.i32(i32 0, i32 [[TMP15]]) +; CHECK-NEXT: [[TMP24:%.*]] = call i32 @llvm.amdgcn.waterfall.readfirstlane.i32.i32(i32 [[TMP23]], i32 [[TMP15]]) +; CHECK-NEXT: [[TMP25:%.*]] = sext i32 [[TMP24]] to i64 +; CHECK-NEXT: [[TMP26:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP9]], i64 [[TMP25]] +; CHECK-NEXT: [[TMP27:%.*]] = load <8 x i32>, ptr addrspace(4) [[TMP26]], align 32, !invariant.load !10 +; CHECK-NEXT: [[TMP28:%.*]] = sext i32 [[TMP24]] to i64 +; CHECK-NEXT: [[TMP29:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP14]], i64 [[TMP28]] +; CHECK-NEXT: [[TMP30:%.*]] = load <4 x i32>, ptr addrspace(4) [[TMP29]], align 16, !invariant.load !10 +; CHECK-NEXT: [[TMP31:%.*]] = call reassoc nnan nsz arcp contract afn <4 x float> @llvm.amdgcn.image.sample.2d.v4f32.f32(i32 15, float 0.000000e+00, float 0.000000e+00, <8 x i32> [[TMP27]], <4 x i32> [[TMP30]], i1 false, i32 0, i32 0) +; CHECK-NEXT: [[TMP32]] = call reassoc nnan nsz arcp contract afn <4 x float> @llvm.amdgcn.waterfall.end.v4f32(i32 [[TMP23]], <4 x float> [[TMP31]]) +; CHECK-NEXT: [[TMP33:%.*]] = fadd <4 x float> [[PHI_IMG]], +; CHECK-NEXT: [[IND]] = add i32 [[PHI_IND]], 1 +; CHECK-NEXT: [[COND:%.*]] = icmp ne i32 [[IND]], 1000 +; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]] +; CHECK: exit: +; CHECK-NEXT: [[TMP34:%.*]] = call i32 @llvm.amdgcn.waterfall.begin.i32(i32 0, i32 [[TMP18]]) +; CHECK-NEXT: [[TMP35:%.*]] = call i32 @llvm.amdgcn.waterfall.readfirstlane.i32.i32(i32 [[TMP34]], i32 [[TMP18]]) +; CHECK-NEXT: [[TMP36:%.*]] = sext i32 [[TMP35]] to i64 +; CHECK-NEXT: [[TMP37:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP14]], i64 [[TMP36]] +; CHECK-NEXT: [[TMP38:%.*]] = load <4 x i32>, ptr addrspace(4) [[TMP37]], align 16, !invariant.load !10 +; CHECK-NEXT: [[TMP39:%.*]] = call <4 x i32> @llvm.amdgcn.waterfall.last.use.v4i32(i32 [[TMP34]], <4 x i32> [[TMP38]]) +; CHECK-NEXT: call void @llvm.amdgcn.struct.buffer.store.format.v4f32(<4 x float> [[TMP33]], <4 x i32> [[TMP39]], i32 1, i32 0, i32 0, i32 0) +; CHECK-NEXT: ret void +; diff --git a/lgc/test/scalarizationOfDescriptorLoadsTest15.ll b/lgc/test/scalarizationOfDescriptorLoadsTest15.ll new file mode 100644 index 0000000000..8975912add --- /dev/null +++ b/lgc/test/scalarizationOfDescriptorLoadsTest15.ll @@ -0,0 +1,144 @@ +; NOTE: Assertions have been autogenerated by tool/update_llpc_test_checks.py UTC_ARGS: --tool lgc +; RUN: lgc -mcpu=gfx1010 -print-after=lgc-builder-replayer -o - %s 2>&1 | FileCheck --check-prefixes=CHECK %s +; ModuleID = 'lgcPipeline' +source_filename = "llpc_fragment_7" +target datalayout = "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-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-p32:32:32" +target triple = "amdgcn--amdpal" + +; Function Attrs: nounwind +define dllexport spir_func void @lgc.shader.FS.main() local_unnamed_addr #0 !spirv.ExecutionModel !8 !lgc.shaderstage !9 { +.entry: + %0 = call i32 (...) @lgc.create.read.generic.input.i32(i32 3, i32 0, i32 0, i32 0, i32 17, i32 poison) + %1 = call ptr addrspace(4) (...) @lgc.create.get.desc.ptr.p4(i32 1, i32 1, i64 0, i32 7) + %2 = call ptr addrspace(4) (...) @lgc.create.get.desc.ptr.p4(i32 2, i32 2, i64 0, i32 7) + br label %loop + +loop: + %phi.ind = phi i32 [ 0, %.entry ], [ %ind, %loop ] + %phi.img = phi <4 x float> [ , %.entry ], [ %11, %loop ] + %a = call i32 (...) @lgc.create.get.desc.stride.i32(i32 1, i32 1, i64 0, i32 7) + %b = call i32 (...) @lgc.create.get.desc.stride.i32(i32 2, i32 2, i64 0, i32 7) + %3 = mul i32 %phi.ind, %a + %4 = sext i32 %3 to i64 + %5 = getelementptr i8, ptr addrspace(4) %1, i64 %4 + %6 = mul i32 %phi.ind, %b + %7 = sext i32 %6 to i64 + %8 = getelementptr i8, ptr addrspace(4) %2, i64 %7 + %9 = load <4 x i32>, ptr addrspace(4) %8, align 16, !invariant.load !10 + %10 = load <8 x i32>, ptr addrspace(4) %5, align 32, !invariant.load !10 + %11 = call reassoc nnan nsz arcp contract afn <4 x float> (...) @lgc.create.image.sample.v4f32(i32 1, i32 24, <8 x i32> %10, <4 x i32> %9, i32 1, <2 x float> zeroinitializer) + %12 = fadd <4 x float> %phi.img, + call void (...) @lgc.create.image.store(<4 x float> %12, i32 0, i32 8, <4 x i32> %9, i32 1) + %ind = add i32 %phi.ind, 1 + %cond = icmp ne i32 %ind, 1000 + br i1 %cond, label %loop, label %exit + +exit: + ret void +} + +declare spir_func void @spirv.NonUniform.i32(i32) local_unnamed_addr + +; Function Attrs: nounwind memory(none) +declare !lgc.create.opcode !11 ptr addrspace(4) @lgc.create.get.desc.ptr.p4(...) local_unnamed_addr #1 + +; Function Attrs: nounwind memory(none) +declare !lgc.create.opcode !12 i32 @lgc.create.get.desc.stride.i32(...) local_unnamed_addr #1 + +declare spir_func void @"spirv.NonUniform.s[s[p4,i32,i32,i32],s[p4,i32,i32]]"({ { ptr addrspace(4), i32, i32, i32 }, { ptr addrspace(4), i32, i32 } }) local_unnamed_addr + +declare spir_func void @"spirv.NonUniform.s[a3v8i32,s[v4i32,i32]]"({ [3 x <8 x i32>], { <4 x i32>, i32 } }) local_unnamed_addr + +; Function Attrs: nounwind willreturn memory(read) +declare !lgc.create.opcode !13 <4 x float> @lgc.create.image.sample.v4f32(...) local_unnamed_addr #2 + +; Function Attrs: nounwind willreturn memory(read) +declare !lgc.create.opcode !14 i32 @lgc.create.read.generic.input.i32(...) local_unnamed_addr #2 + +; Function Attrs: nounwind memory(write) +declare void @lgc.create.image.store(...) local_unnamed_addr #4 + +attributes #0 = { nounwind "denormal-fp-math-f32"="preserve-sign" } +attributes #1 = { nounwind memory(none) } +attributes #2 = { nounwind willreturn memory(read) } +attributes #3 = { nounwind } +attributes #4 = { nounwind memory(write) } + +!lgc.client = !{!0} +!lgc.unlinked = !{!1} +!lgc.options = !{!2} +!lgc.options.FS = !{!3} +!lgc.user.data.nodes = !{!4, !5} +!lgc.color.export.formats = !{!6} +!amdgpu.pal.metadata.msgpack = !{!7} + +!0 = !{!"Vulkan"} +!1 = !{i32 1} +!2 = !{i32 -158725823, i32 1419665388, i32 -1015833383, i32 -491143713, i32 1, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 1, i32 256, i32 256, i32 2, i32 1} +!3 = !{i32 -1822594139, i32 1920663194, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 64, i32 0, i32 0, i32 3, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 20, i32 1800, i32 0, i32 0, i32 1} +!4 = !{!"DescriptorTableVaPtr", i32 7, i32 64, i32 0, i32 1, i32 1} +!5 = !{!"DescriptorCombinedTexture", i32 3, i32 64, i32 0, i32 192, i64 0, i32 7, i32 12} +!6 = !{i32 14, i32 7, i32 0, i32 0, i32 15} +!7 = !{!"\82\B0amdpal.pipelines\91\83\B0.spill_threshold\CD\FF\FF\B0.user_data_limit\00\AF.xgl_cache_info\82\B3.128_bit_cache_hash\92\CF\E8\D2\98>j\B9B\94\CF2\DEF\BF\9Fx\BC1\AD.llpc_version\A470.1\AEamdpal.version\92\03\00"} +!8 = !{i32 4} +!9 = !{i32 6} +!10 = !{} +!11 = !{i32 56} +!12 = !{i32 55} +!13 = !{i32 61} +!14 = !{i32 71} +!15 = !{i32 74} + +; CHECK-LABEL: @lgc.shader.FS.main( +; CHECK-NEXT: .entry: +; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.amdgcn.s.getpc() +; CHECK-NEXT: [[TMP1:%.*]] = bitcast i64 [[TMP0]] to <2 x i32> +; CHECK-NEXT: [[TMP2:%.*]] = call i64 @llvm.amdgcn.s.getpc() +; CHECK-NEXT: [[TMP3:%.*]] = bitcast i64 [[TMP2]] to <2 x i32> +; CHECK-NEXT: [[TMP4:%.*]] = call i32 (...) @lgc.input.import.interpolated.i32(i1 false, i32 3, i32 0, i32 0, i32 poison, i32 1, i32 poison) +; CHECK-NEXT: [[TMP5:%.*]] = call i32 @lgc.load.user.data.i32(i32 0) +; CHECK-NEXT: [[TMP6:%.*]] = insertelement <2 x i32> [[TMP3]], i32 [[TMP5]], i64 0 +; CHECK-NEXT: [[TMP7:%.*]] = bitcast <2 x i32> [[TMP6]] to i64 +; CHECK-NEXT: [[TMP8:%.*]] = inttoptr i64 [[TMP7]] to ptr addrspace(4) +; CHECK-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP8]], i32 0 +; CHECK-NEXT: [[TMP10:%.*]] = call i32 @lgc.load.user.data.i32(i32 0) +; CHECK-NEXT: [[TMP11:%.*]] = insertelement <2 x i32> [[TMP1]], i32 [[TMP10]], i64 0 +; CHECK-NEXT: [[TMP12:%.*]] = bitcast <2 x i32> [[TMP11]] to i64 +; CHECK-NEXT: [[TMP13:%.*]] = inttoptr i64 [[TMP12]] to ptr addrspace(4) +; CHECK-NEXT: [[TMP14:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP13]], i32 32 +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: [[PHI_IND:%.*]] = phi i32 [ 0, [[DOTENTRY:%.*]] ], [ [[IND:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[PHI_IMG:%.*]] = phi <4 x float> [ , [[DOTENTRY]] ], [ [[TMP32:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[TMP15:%.*]] = mul i32 [[PHI_IND]], 48 +; CHECK-NEXT: [[TMP16:%.*]] = sext i32 [[TMP15]] to i64 +; CHECK-NEXT: [[TMP17:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP9]], i64 [[TMP16]] +; CHECK-NEXT: [[TMP18:%.*]] = mul i32 [[PHI_IND]], 48 +; CHECK-NEXT: [[TMP19:%.*]] = sext i32 [[TMP18]] to i64 +; CHECK-NEXT: [[TMP20:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP14]], i64 [[TMP19]] +; CHECK-NEXT: [[TMP21:%.*]] = load <4 x i32>, ptr addrspace(4) [[TMP20]], align 16, !invariant.load !10 +; CHECK-NEXT: [[TMP22:%.*]] = load <8 x i32>, ptr addrspace(4) [[TMP17]], align 32, !invariant.load !10 +; CHECK-NEXT: [[TMP23:%.*]] = call i32 @llvm.amdgcn.waterfall.begin.i32(i32 0, i32 [[TMP15]]) +; CHECK-NEXT: [[TMP24:%.*]] = call i32 @llvm.amdgcn.waterfall.readfirstlane.i32.i32(i32 [[TMP23]], i32 [[TMP15]]) +; CHECK-NEXT: [[TMP25:%.*]] = sext i32 [[TMP24]] to i64 +; CHECK-NEXT: [[TMP26:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP9]], i64 [[TMP25]] +; CHECK-NEXT: [[TMP27:%.*]] = load <8 x i32>, ptr addrspace(4) [[TMP26]], align 32, !invariant.load !10 +; CHECK-NEXT: [[TMP28:%.*]] = sext i32 [[TMP24]] to i64 +; CHECK-NEXT: [[TMP29:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP14]], i64 [[TMP28]] +; CHECK-NEXT: [[TMP30:%.*]] = load <4 x i32>, ptr addrspace(4) [[TMP29]], align 16, !invariant.load !10 +; CHECK-NEXT: [[TMP31:%.*]] = call reassoc nnan nsz arcp contract afn <4 x float> @llvm.amdgcn.image.sample.2d.v4f32.f32(i32 15, float 0.000000e+00, float 0.000000e+00, <8 x i32> [[TMP27]], <4 x i32> [[TMP30]], i1 false, i32 0, i32 0) +; CHECK-NEXT: [[TMP32]] = call reassoc nnan nsz arcp contract afn <4 x float> @llvm.amdgcn.waterfall.end.v4f32(i32 [[TMP23]], <4 x float> [[TMP31]]) +; CHECK-NEXT: [[TMP33:%.*]] = fadd <4 x float> [[PHI_IMG]], +; CHECK-NEXT: [[TMP34:%.*]] = call i32 @llvm.amdgcn.waterfall.begin.i32(i32 0, i32 [[TMP18]]) +; CHECK-NEXT: [[TMP35:%.*]] = call i32 @llvm.amdgcn.waterfall.readfirstlane.i32.i32(i32 [[TMP34]], i32 [[TMP18]]) +; CHECK-NEXT: [[TMP36:%.*]] = sext i32 [[TMP35]] to i64 +; CHECK-NEXT: [[TMP37:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP14]], i64 [[TMP36]] +; CHECK-NEXT: [[TMP38:%.*]] = load <4 x i32>, ptr addrspace(4) [[TMP37]], align 16, !invariant.load !10 +; CHECK-NEXT: [[TMP39:%.*]] = call <4 x i32> @llvm.amdgcn.waterfall.last.use.v4i32(i32 [[TMP34]], <4 x i32> [[TMP38]]) +; CHECK-NEXT: call void @llvm.amdgcn.struct.buffer.store.format.v4f32(<4 x float> [[TMP33]], <4 x i32> [[TMP39]], i32 1, i32 0, i32 0, i32 0) +; CHECK-NEXT: [[IND]] = add i32 [[PHI_IND]], 1 +; CHECK-NEXT: [[COND:%.*]] = icmp ne i32 [[IND]], 1000 +; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]] +; CHECK: exit: +; CHECK-NEXT: ret void +; diff --git a/lgc/test/scalarizationOfDescriptorLoadsTest16.ll b/lgc/test/scalarizationOfDescriptorLoadsTest16.ll new file mode 100644 index 0000000000..29562e3d55 --- /dev/null +++ b/lgc/test/scalarizationOfDescriptorLoadsTest16.ll @@ -0,0 +1,130 @@ +; NOTE: Assertions have been autogenerated by tool/update_llpc_test_checks.py UTC_ARGS: --tool lgc +; RUN: lgc -mcpu=gfx1010 -print-after=lgc-builder-replayer -o - %s 2>&1 | FileCheck --check-prefixes=CHECK %s +; ModuleID = 'lgcPipeline' +source_filename = "llpc_fragment_7" +target datalayout = "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-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-p32:32:32" +target triple = "amdgcn--amdpal" + +; Function Attrs: nounwind +define dllexport spir_func void @lgc.shader.FS.main() local_unnamed_addr #0 !spirv.ExecutionModel !8 !lgc.shaderstage !9 { +.entry: + %0 = call i32 (...) @lgc.create.read.generic.input.i32(i32 3, i32 0, i32 0, i32 0, i32 17, i32 poison) + %1 = call ptr addrspace(4) (...) @lgc.create.get.desc.ptr.p4(i32 1, i32 1, i64 0, i32 7) + %2 = call ptr addrspace(4) (...) @lgc.create.get.desc.ptr.p4(i32 2, i32 2, i64 0, i32 7) + br label %loop + +loop: + %phi.ind = phi i32 [ 0, %.entry ], [ %ind, %loop ] + %a = call i32 (...) @lgc.create.get.desc.stride.i32(i32 1, i32 1, i64 0, i32 7) + %b = call i32 (...) @lgc.create.get.desc.stride.i32(i32 2, i32 2, i64 0, i32 7) + %3 = mul i32 %phi.ind, %a + %4 = sext i32 %3 to i64 + %5 = getelementptr i8, ptr addrspace(4) %1, i64 %4 + %6 = mul i32 %phi.ind, %b + %7 = sext i32 %6 to i64 + %8 = getelementptr i8, ptr addrspace(4) %2, i64 %7 + %9 = load <4 x i32>, ptr addrspace(4) %8, align 16, !invariant.load !10 + %10 = load <4 x i32>, ptr addrspace(4) %5, align 32, !invariant.load !10 + call void (...) @lgc.create.image.store(<4 x i32> %10, i32 0, i32 8, <4 x i32> %9, i32 1) + %ind = add i32 %phi.ind, 1 + %cond = icmp ne i32 %ind, 1000 + br i1 %cond, label %loop, label %exit + +exit: + ret void +} + +declare spir_func void @spirv.NonUniform.i32(i32) local_unnamed_addr + +; Function Attrs: nounwind memory(none) +declare !lgc.create.opcode !11 ptr addrspace(4) @lgc.create.get.desc.ptr.p4(...) local_unnamed_addr #1 + +; Function Attrs: nounwind memory(none) +declare !lgc.create.opcode !12 i32 @lgc.create.get.desc.stride.i32(...) local_unnamed_addr #1 + +declare spir_func void @"spirv.NonUniform.s[s[p4,i32,i32,i32],s[p4,i32,i32]]"({ { ptr addrspace(4), i32, i32, i32 }, { ptr addrspace(4), i32, i32 } }) local_unnamed_addr + +declare spir_func void @"spirv.NonUniform.s[a3v8i32,s[v4i32,i32]]"({ [3 x <8 x i32>], { <4 x i32>, i32 } }) local_unnamed_addr + +; Function Attrs: nounwind willreturn memory(read) +declare !lgc.create.opcode !13 <4 x float> @lgc.create.image.sample.v4f32(...) local_unnamed_addr #2 + +; Function Attrs: nounwind willreturn memory(read) +declare !lgc.create.opcode !14 i32 @lgc.create.read.generic.input.i32(...) local_unnamed_addr #2 + +; Function Attrs: nounwind memory(write) +declare void @lgc.create.image.store(...) local_unnamed_addr #4 + +attributes #0 = { nounwind "denormal-fp-math-f32"="preserve-sign" } +attributes #1 = { nounwind memory(none) } +attributes #2 = { nounwind willreturn memory(read) } +attributes #3 = { nounwind } +attributes #4 = { nounwind memory(write) } + +!lgc.client = !{!0} +!lgc.unlinked = !{!1} +!lgc.options = !{!2} +!lgc.options.FS = !{!3} +!lgc.user.data.nodes = !{!4, !5} +!lgc.color.export.formats = !{!6} +!amdgpu.pal.metadata.msgpack = !{!7} + +!0 = !{!"Vulkan"} +!1 = !{i32 1} +!2 = !{i32 -158725823, i32 1419665388, i32 -1015833383, i32 -491143713, i32 1, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 1, i32 256, i32 256, i32 2, i32 1} +!3 = !{i32 -1822594139, i32 1920663194, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 64, i32 0, i32 0, i32 3, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 20, i32 1800, i32 0, i32 0, i32 1} +!4 = !{!"DescriptorTableVaPtr", i32 7, i32 64, i32 0, i32 1, i32 1} +!5 = !{!"DescriptorCombinedTexture", i32 3, i32 64, i32 0, i32 192, i64 0, i32 7, i32 12} +!6 = !{i32 14, i32 7, i32 0, i32 0, i32 15} +!7 = !{!"\82\B0amdpal.pipelines\91\83\B0.spill_threshold\CD\FF\FF\B0.user_data_limit\00\AF.xgl_cache_info\82\B3.128_bit_cache_hash\92\CF\E8\D2\98>j\B9B\94\CF2\DEF\BF\9Fx\BC1\AD.llpc_version\A470.1\AEamdpal.version\92\03\00"} +!8 = !{i32 4} +!9 = !{i32 6} +!10 = !{} +!11 = !{i32 56} +!12 = !{i32 55} +!13 = !{i32 61} +!14 = !{i32 71} +!15 = !{i32 74} + +; CHECK-LABEL: @lgc.shader.FS.main( +; CHECK-NEXT: .entry: +; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.amdgcn.s.getpc() +; CHECK-NEXT: [[TMP1:%.*]] = bitcast i64 [[TMP0]] to <2 x i32> +; CHECK-NEXT: [[TMP2:%.*]] = call i64 @llvm.amdgcn.s.getpc() +; CHECK-NEXT: [[TMP3:%.*]] = bitcast i64 [[TMP2]] to <2 x i32> +; CHECK-NEXT: [[TMP4:%.*]] = call i32 (...) @lgc.input.import.interpolated.i32(i1 false, i32 3, i32 0, i32 0, i32 poison, i32 1, i32 poison) +; CHECK-NEXT: [[TMP5:%.*]] = call i32 @lgc.load.user.data.i32(i32 0) +; CHECK-NEXT: [[TMP6:%.*]] = insertelement <2 x i32> [[TMP3]], i32 [[TMP5]], i64 0 +; CHECK-NEXT: [[TMP7:%.*]] = bitcast <2 x i32> [[TMP6]] to i64 +; CHECK-NEXT: [[TMP8:%.*]] = inttoptr i64 [[TMP7]] to ptr addrspace(4) +; CHECK-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP8]], i32 0 +; CHECK-NEXT: [[TMP10:%.*]] = call i32 @lgc.load.user.data.i32(i32 0) +; CHECK-NEXT: [[TMP11:%.*]] = insertelement <2 x i32> [[TMP1]], i32 [[TMP10]], i64 0 +; CHECK-NEXT: [[TMP12:%.*]] = bitcast <2 x i32> [[TMP11]] to i64 +; CHECK-NEXT: [[TMP13:%.*]] = inttoptr i64 [[TMP12]] to ptr addrspace(4) +; CHECK-NEXT: [[TMP14:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP13]], i32 32 +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: [[PHI_IND:%.*]] = phi i32 [ 0, [[DOTENTRY:%.*]] ], [ [[IND:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[TMP15:%.*]] = mul i32 [[PHI_IND]], 48 +; CHECK-NEXT: [[TMP16:%.*]] = sext i32 [[TMP15]] to i64 +; CHECK-NEXT: [[TMP17:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP9]], i64 [[TMP16]] +; CHECK-NEXT: [[TMP18:%.*]] = mul i32 [[PHI_IND]], 48 +; CHECK-NEXT: [[TMP19:%.*]] = sext i32 [[TMP18]] to i64 +; CHECK-NEXT: [[TMP20:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP14]], i64 [[TMP19]] +; CHECK-NEXT: [[TMP21:%.*]] = load <4 x i32>, ptr addrspace(4) [[TMP20]], align 16, !invariant.load !10 +; CHECK-NEXT: [[TMP22:%.*]] = load <4 x i32>, ptr addrspace(4) [[TMP17]], align 32, !invariant.load !10 +; CHECK-NEXT: [[TMP23:%.*]] = bitcast <4 x i32> [[TMP22]] to <4 x float> +; CHECK-NEXT: [[TMP24:%.*]] = call i32 @llvm.amdgcn.waterfall.begin.i32(i32 0, i32 [[TMP18]]) +; CHECK-NEXT: [[TMP25:%.*]] = call i32 @llvm.amdgcn.waterfall.readfirstlane.i32.i32(i32 [[TMP24]], i32 [[TMP18]]) +; CHECK-NEXT: [[TMP26:%.*]] = sext i32 [[TMP25]] to i64 +; CHECK-NEXT: [[TMP27:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP14]], i64 [[TMP26]] +; CHECK-NEXT: [[TMP28:%.*]] = load <4 x i32>, ptr addrspace(4) [[TMP27]], align 16, !invariant.load !10 +; CHECK-NEXT: [[TMP29:%.*]] = call <4 x i32> @llvm.amdgcn.waterfall.last.use.v4i32(i32 [[TMP24]], <4 x i32> [[TMP28]]) +; CHECK-NEXT: call void @llvm.amdgcn.struct.buffer.store.format.v4f32(<4 x float> [[TMP23]], <4 x i32> [[TMP29]], i32 1, i32 0, i32 0, i32 0) +; CHECK-NEXT: [[IND]] = add i32 [[PHI_IND]], 1 +; CHECK-NEXT: [[COND:%.*]] = icmp ne i32 [[IND]], 1000 +; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]] +; CHECK: exit: +; CHECK-NEXT: ret void +; diff --git a/lgc/test/scalarizationOfDescriptorLoadsTest7.ll b/lgc/test/scalarizationOfDescriptorLoadsTest7.ll new file mode 100644 index 0000000000..ad9cf8ba94 --- /dev/null +++ b/lgc/test/scalarizationOfDescriptorLoadsTest7.ll @@ -0,0 +1,132 @@ +; NOTE: Assertions have been autogenerated by tool/update_llpc_test_checks.py UTC_ARGS: --tool lgc +; RUN: lgc -mcpu=gfx1010 -print-after=lgc-builder-replayer -o - %s 2>&1 | FileCheck --check-prefixes=CHECK %s +; ModuleID = 'lgcPipeline' +source_filename = "llpc_fragment_7" +target datalayout = "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-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-p32:32:32" +target triple = "amdgcn--amdpal" + +; Function Attrs: nounwind +define dllexport spir_func void @lgc.shader.FS.main() local_unnamed_addr #0 !spirv.ExecutionModel !8 !lgc.shaderstage !9 { +.entry: + %0 = call i32 (...) @lgc.create.read.generic.input.i32(i32 3, i32 0, i32 0, i32 0, i32 17, i32 poison) + %1 = call ptr addrspace(4) (...) @lgc.create.get.desc.ptr.p4(i32 1, i32 1, i64 0, i32 7) + %2 = call i32 (...) @lgc.create.get.desc.stride.i32(i32 1, i32 1, i64 0, i32 7) + %3 = call ptr addrspace(4) (...) @lgc.create.get.desc.ptr.p4(i32 2, i32 2, i64 0, i32 7) + %4 = call i32 (...) @lgc.create.get.desc.stride.i32(i32 2, i32 2, i64 0, i32 7) + br label %bb1 + +bb1: + %5 = mul i32 %0, %2 + %6 = sext i32 %5 to i64 + %7 = getelementptr i8, ptr addrspace(4) %1, i64 %6 + br label %bb2 + +bb2: + %8 = mul i32 %0, %4 + %9 = sext i32 %8 to i64 + %10 = getelementptr i8, ptr addrspace(4) %3, i64 %9 + %11 = load <4 x i32>, ptr addrspace(4) %10, align 16, !invariant.load !10 + br label %bb3 + +bb3: + %12 = load <8 x i32>, ptr addrspace(4) %7, align 32, !invariant.load !10 + %13 = call reassoc nnan nsz arcp contract afn <4 x float> (...) @lgc.create.image.sample.v4f32(i32 1, i32 24, <8 x i32> %12, <4 x i32> %11, i32 1, <2 x float> zeroinitializer) + call void (...) @lgc.create.write.generic.output(<4 x float> %13, i32 0, i32 0, i32 0, i32 0, i32 0, i32 poison) + ret void +} + +declare spir_func void @spirv.NonUniform.i32(i32) local_unnamed_addr + +; Function Attrs: nounwind memory(none) +declare !lgc.create.opcode !11 ptr addrspace(4) @lgc.create.get.desc.ptr.p4(...) local_unnamed_addr #1 + +; Function Attrs: nounwind memory(none) +declare !lgc.create.opcode !12 i32 @lgc.create.get.desc.stride.i32(...) local_unnamed_addr #1 + +declare spir_func void @"spirv.NonUniform.s[s[p4,i32,i32,i32],s[p4,i32,i32]]"({ { ptr addrspace(4), i32, i32, i32 }, { ptr addrspace(4), i32, i32 } }) local_unnamed_addr + +declare spir_func void @"spirv.NonUniform.s[a3v8i32,s[v4i32,i32]]"({ [3 x <8 x i32>], { <4 x i32>, i32 } }) local_unnamed_addr + +; Function Attrs: nounwind willreturn memory(read) +declare !lgc.create.opcode !13 <4 x float> @lgc.create.image.sample.v4f32(...) local_unnamed_addr #2 + +; Function Attrs: nounwind willreturn memory(read) +declare !lgc.create.opcode !14 i32 @lgc.create.read.generic.input.i32(...) local_unnamed_addr #2 + +; Function Attrs: nounwind +declare !lgc.create.opcode !15 void @lgc.create.write.generic.output(...) local_unnamed_addr #3 + +attributes #0 = { nounwind "denormal-fp-math-f32"="preserve-sign" } +attributes #1 = { nounwind memory(none) } +attributes #2 = { nounwind willreturn memory(read) } +attributes #3 = { nounwind } + +!lgc.client = !{!0} +!lgc.unlinked = !{!1} +!lgc.options = !{!2} +!lgc.options.FS = !{!3} +!lgc.user.data.nodes = !{!4, !5} +!lgc.color.export.formats = !{!6} +!amdgpu.pal.metadata.msgpack = !{!7} + +!0 = !{!"Vulkan"} +!1 = !{i32 1} +!2 = !{i32 -158725823, i32 1419665388, i32 -1015833383, i32 -491143713, i32 1, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 1, i32 256, i32 256, i32 2, i32 1} +!3 = !{i32 -1822594139, i32 1920663194, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 64, i32 0, i32 0, i32 3, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 20, i32 1800, i32 0, i32 0, i32 1} +!4 = !{!"DescriptorTableVaPtr", i32 7, i32 64, i32 0, i32 1, i32 1} +!5 = !{!"DescriptorCombinedTexture", i32 3, i32 64, i32 0, i32 192, i64 0, i32 7, i32 12} +!6 = !{i32 14, i32 7, i32 0, i32 0, i32 15} +!7 = !{!"\82\B0amdpal.pipelines\91\83\B0.spill_threshold\CD\FF\FF\B0.user_data_limit\00\AF.xgl_cache_info\82\B3.128_bit_cache_hash\92\CF\E8\D2\98>j\B9B\94\CF2\DEF\BF\9Fx\BC1\AD.llpc_version\A470.1\AEamdpal.version\92\03\00"} +!8 = !{i32 4} +!9 = !{i32 6} +!10 = !{} +!11 = !{i32 56} +!12 = !{i32 55} +!13 = !{i32 61} +!14 = !{i32 71} +!15 = !{i32 74} + +; CHECK-LABEL: @lgc.shader.FS.main( +; CHECK-NEXT: .entry: +; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.amdgcn.s.getpc() +; CHECK-NEXT: [[TMP1:%.*]] = bitcast i64 [[TMP0]] to <2 x i32> +; CHECK-NEXT: [[TMP2:%.*]] = call i64 @llvm.amdgcn.s.getpc() +; CHECK-NEXT: [[TMP3:%.*]] = bitcast i64 [[TMP2]] to <2 x i32> +; CHECK-NEXT: [[TMP4:%.*]] = call i32 (...) @lgc.input.import.interpolated.i32(i1 false, i32 3, i32 0, i32 0, i32 poison, i32 1, i32 poison) +; CHECK-NEXT: [[TMP5:%.*]] = call i32 @lgc.load.user.data.i32(i32 0) +; CHECK-NEXT: [[TMP6:%.*]] = insertelement <2 x i32> [[TMP3]], i32 [[TMP5]], i64 0 +; CHECK-NEXT: [[TMP7:%.*]] = bitcast <2 x i32> [[TMP6]] to i64 +; CHECK-NEXT: [[TMP8:%.*]] = inttoptr i64 [[TMP7]] to ptr addrspace(4) +; CHECK-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP8]], i32 0 +; CHECK-NEXT: [[TMP10:%.*]] = call i32 @lgc.load.user.data.i32(i32 0) +; CHECK-NEXT: [[TMP11:%.*]] = insertelement <2 x i32> [[TMP1]], i32 [[TMP10]], i64 0 +; CHECK-NEXT: [[TMP12:%.*]] = bitcast <2 x i32> [[TMP11]] to i64 +; CHECK-NEXT: [[TMP13:%.*]] = inttoptr i64 [[TMP12]] to ptr addrspace(4) +; CHECK-NEXT: [[TMP14:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP13]], i32 32 +; CHECK-NEXT: br label [[BB1:%.*]] +; CHECK: bb1: +; CHECK-NEXT: [[TMP15:%.*]] = mul i32 [[TMP4]], 48 +; CHECK-NEXT: [[TMP16:%.*]] = sext i32 [[TMP15]] to i64 +; CHECK-NEXT: [[TMP17:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP9]], i64 [[TMP16]] +; CHECK-NEXT: br label [[BB2:%.*]] +; CHECK: bb2: +; CHECK-NEXT: [[TMP18:%.*]] = mul i32 [[TMP4]], 48 +; CHECK-NEXT: [[TMP19:%.*]] = sext i32 [[TMP18]] to i64 +; CHECK-NEXT: [[TMP20:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP14]], i64 [[TMP19]] +; CHECK-NEXT: [[TMP21:%.*]] = load <4 x i32>, ptr addrspace(4) [[TMP20]], align 16, !invariant.load !10 +; CHECK-NEXT: br label [[BB3:%.*]] +; CHECK: bb3: +; CHECK-NEXT: [[TMP22:%.*]] = load <8 x i32>, ptr addrspace(4) [[TMP17]], align 32, !invariant.load !10 +; CHECK-NEXT: [[TMP23:%.*]] = call i32 @llvm.amdgcn.waterfall.begin.i32(i32 0, i32 [[TMP15]]) +; CHECK-NEXT: [[TMP24:%.*]] = call i32 @llvm.amdgcn.waterfall.readfirstlane.i32.i32(i32 [[TMP23]], i32 [[TMP15]]) +; CHECK-NEXT: [[TMP25:%.*]] = sext i32 [[TMP24]] to i64 +; CHECK-NEXT: [[TMP26:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP9]], i64 [[TMP25]] +; CHECK-NEXT: [[TMP27:%.*]] = load <8 x i32>, ptr addrspace(4) [[TMP26]], align 32, !invariant.load !10 +; CHECK-NEXT: [[TMP28:%.*]] = sext i32 [[TMP24]] to i64 +; CHECK-NEXT: [[TMP29:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP14]], i64 [[TMP28]] +; CHECK-NEXT: [[TMP30:%.*]] = load <4 x i32>, ptr addrspace(4) [[TMP29]], align 16, !invariant.load !10 +; CHECK-NEXT: [[TMP31:%.*]] = call reassoc nnan nsz arcp contract afn <4 x float> @llvm.amdgcn.image.sample.2d.v4f32.f32(i32 15, float 0.000000e+00, float 0.000000e+00, <8 x i32> [[TMP27]], <4 x i32> [[TMP30]], i1 false, i32 0, i32 0) +; CHECK-NEXT: [[TMP32:%.*]] = call reassoc nnan nsz arcp contract afn <4 x float> @llvm.amdgcn.waterfall.end.v4f32(i32 [[TMP23]], <4 x float> [[TMP31]]) +; CHECK-NEXT: call void @lgc.output.export.generic.i32.i32.v4f32(i32 0, i32 0, <4 x float> [[TMP32]]) #[[ATTR5:[0-9]+]] +; CHECK-NEXT: ret void +; diff --git a/lgc/test/scalarizationOfDescriptorLoadsTest8.ll b/lgc/test/scalarizationOfDescriptorLoadsTest8.ll new file mode 100644 index 0000000000..430b839c92 --- /dev/null +++ b/lgc/test/scalarizationOfDescriptorLoadsTest8.ll @@ -0,0 +1,136 @@ +; NOTE: Assertions have been autogenerated by tool/update_llpc_test_checks.py UTC_ARGS: --tool lgc +; RUN: lgc -mcpu=gfx1010 -print-after=lgc-builder-replayer -o - %s 2>&1 | FileCheck --check-prefixes=CHECK %s +; ModuleID = 'lgcPipeline' +source_filename = "llpc_fragment_7" +target datalayout = "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-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-p32:32:32" +target triple = "amdgcn--amdpal" + +; Function Attrs: nounwind +define dllexport spir_func void @lgc.shader.FS.main() local_unnamed_addr #0 !spirv.ExecutionModel !8 !lgc.shaderstage !9 { +.entry: + %0 = call i32 (...) @lgc.create.read.generic.input.i32(i32 3, i32 0, i32 0, i32 0, i32 17, i32 poison) + %1 = call ptr addrspace(4) (...) @lgc.create.get.desc.ptr.p4(i32 1, i32 1, i64 0, i32 7) + %2 = call ptr addrspace(4) (...) @lgc.create.get.desc.ptr.p4(i32 2, i32 2, i64 0, i32 7) + %cond = icmp ne i32 %0, 0 + br i1 %cond, label %bb1, label %bb2 + +bb1: + %a = call i32 (...) @lgc.create.get.desc.stride.i32(i32 1, i32 1, i64 0, i32 7) + br label %bb3 + +bb2: + %b = call i32 (...) @lgc.create.get.desc.stride.i32(i32 2, i32 2, i64 0, i32 7) + br label %bb3 + +bb3: + %phi = phi i32 [ %a, %bb1 ], [ %b, %bb2 ] + %3 = mul i32 %0, %phi + %4 = sext i32 %3 to i64 + %5 = getelementptr i8, ptr addrspace(4) %1, i64 %4 + %6 = mul i32 %0, %phi + %7 = sext i32 %6 to i64 + %8 = getelementptr i8, ptr addrspace(4) %2, i64 %7 + %9 = load <4 x i32>, ptr addrspace(4) %8, align 16, !invariant.load !10 + %10 = load <8 x i32>, ptr addrspace(4) %5, align 32, !invariant.load !10 + %11 = call reassoc nnan nsz arcp contract afn <4 x float> (...) @lgc.create.image.sample.v4f32(i32 1, i32 24, <8 x i32> %10, <4 x i32> %9, i32 1, <2 x float> zeroinitializer) + call void (...) @lgc.create.write.generic.output(<4 x float> %11, i32 0, i32 0, i32 0, i32 0, i32 0, i32 poison) + ret void +} + +declare spir_func void @spirv.NonUniform.i32(i32) local_unnamed_addr + +; Function Attrs: nounwind memory(none) +declare !lgc.create.opcode !11 ptr addrspace(4) @lgc.create.get.desc.ptr.p4(...) local_unnamed_addr #1 + +; Function Attrs: nounwind memory(none) +declare !lgc.create.opcode !12 i32 @lgc.create.get.desc.stride.i32(...) local_unnamed_addr #1 + +declare spir_func void @"spirv.NonUniform.s[s[p4,i32,i32,i32],s[p4,i32,i32]]"({ { ptr addrspace(4), i32, i32, i32 }, { ptr addrspace(4), i32, i32 } }) local_unnamed_addr + +declare spir_func void @"spirv.NonUniform.s[a3v8i32,s[v4i32,i32]]"({ [3 x <8 x i32>], { <4 x i32>, i32 } }) local_unnamed_addr + +; Function Attrs: nounwind willreturn memory(read) +declare !lgc.create.opcode !13 <4 x float> @lgc.create.image.sample.v4f32(...) local_unnamed_addr #2 + +; Function Attrs: nounwind willreturn memory(read) +declare !lgc.create.opcode !14 i32 @lgc.create.read.generic.input.i32(...) local_unnamed_addr #2 + +; Function Attrs: nounwind +declare !lgc.create.opcode !15 void @lgc.create.write.generic.output(...) local_unnamed_addr #3 + +attributes #0 = { nounwind "denormal-fp-math-f32"="preserve-sign" } +attributes #1 = { nounwind memory(none) } +attributes #2 = { nounwind willreturn memory(read) } +attributes #3 = { nounwind } + +!lgc.client = !{!0} +!lgc.unlinked = !{!1} +!lgc.options = !{!2} +!lgc.options.FS = !{!3} +!lgc.user.data.nodes = !{!4, !5} +!lgc.color.export.formats = !{!6} +!amdgpu.pal.metadata.msgpack = !{!7} + +!0 = !{!"Vulkan"} +!1 = !{i32 1} +!2 = !{i32 -158725823, i32 1419665388, i32 -1015833383, i32 -491143713, i32 1, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 1, i32 256, i32 256, i32 2, i32 1} +!3 = !{i32 -1822594139, i32 1920663194, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 64, i32 0, i32 0, i32 3, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 20, i32 1800, i32 0, i32 0, i32 1} +!4 = !{!"DescriptorTableVaPtr", i32 7, i32 64, i32 0, i32 1, i32 1} +!5 = !{!"DescriptorCombinedTexture", i32 3, i32 64, i32 0, i32 192, i64 0, i32 7, i32 12} +!6 = !{i32 14, i32 7, i32 0, i32 0, i32 15} +!7 = !{!"\82\B0amdpal.pipelines\91\83\B0.spill_threshold\CD\FF\FF\B0.user_data_limit\00\AF.xgl_cache_info\82\B3.128_bit_cache_hash\92\CF\E8\D2\98>j\B9B\94\CF2\DEF\BF\9Fx\BC1\AD.llpc_version\A470.1\AEamdpal.version\92\03\00"} +!8 = !{i32 4} +!9 = !{i32 6} +!10 = !{} +!11 = !{i32 56} +!12 = !{i32 55} +!13 = !{i32 61} +!14 = !{i32 71} +!15 = !{i32 74} + +; CHECK-LABEL: @lgc.shader.FS.main( +; CHECK-NEXT: .entry: +; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.amdgcn.s.getpc() +; CHECK-NEXT: [[TMP1:%.*]] = bitcast i64 [[TMP0]] to <2 x i32> +; CHECK-NEXT: [[TMP2:%.*]] = call i64 @llvm.amdgcn.s.getpc() +; CHECK-NEXT: [[TMP3:%.*]] = bitcast i64 [[TMP2]] to <2 x i32> +; CHECK-NEXT: [[TMP4:%.*]] = call i32 (...) @lgc.input.import.interpolated.i32(i1 false, i32 3, i32 0, i32 0, i32 poison, i32 1, i32 poison) +; CHECK-NEXT: [[TMP5:%.*]] = call i32 @lgc.load.user.data.i32(i32 0) +; CHECK-NEXT: [[TMP6:%.*]] = insertelement <2 x i32> [[TMP3]], i32 [[TMP5]], i64 0 +; CHECK-NEXT: [[TMP7:%.*]] = bitcast <2 x i32> [[TMP6]] to i64 +; CHECK-NEXT: [[TMP8:%.*]] = inttoptr i64 [[TMP7]] to ptr addrspace(4) +; CHECK-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP8]], i32 0 +; CHECK-NEXT: [[TMP10:%.*]] = call i32 @lgc.load.user.data.i32(i32 0) +; CHECK-NEXT: [[TMP11:%.*]] = insertelement <2 x i32> [[TMP1]], i32 [[TMP10]], i64 0 +; CHECK-NEXT: [[TMP12:%.*]] = bitcast <2 x i32> [[TMP11]] to i64 +; CHECK-NEXT: [[TMP13:%.*]] = inttoptr i64 [[TMP12]] to ptr addrspace(4) +; CHECK-NEXT: [[TMP14:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP13]], i32 32 +; CHECK-NEXT: [[COND:%.*]] = icmp ne i32 [[TMP4]], 0 +; CHECK-NEXT: br i1 [[COND]], label [[BB1:%.*]], label [[BB2:%.*]] +; CHECK: bb1: +; CHECK-NEXT: br label [[BB3:%.*]] +; CHECK: bb2: +; CHECK-NEXT: br label [[BB3]] +; CHECK: bb3: +; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 48, [[BB1]] ], [ 48, [[BB2]] ] +; CHECK-NEXT: [[TMP15:%.*]] = mul i32 [[TMP4]], [[PHI]] +; CHECK-NEXT: [[TMP16:%.*]] = sext i32 [[TMP15]] to i64 +; CHECK-NEXT: [[TMP17:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP9]], i64 [[TMP16]] +; CHECK-NEXT: [[TMP18:%.*]] = mul i32 [[TMP4]], [[PHI]] +; CHECK-NEXT: [[TMP19:%.*]] = sext i32 [[TMP18]] to i64 +; CHECK-NEXT: [[TMP20:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP14]], i64 [[TMP19]] +; CHECK-NEXT: [[TMP21:%.*]] = load <4 x i32>, ptr addrspace(4) [[TMP20]], align 16, !invariant.load !10 +; CHECK-NEXT: [[TMP22:%.*]] = load <8 x i32>, ptr addrspace(4) [[TMP17]], align 32, !invariant.load !10 +; CHECK-NEXT: [[TMP23:%.*]] = call i32 @llvm.amdgcn.waterfall.begin.i32(i32 0, i32 [[TMP15]]) +; CHECK-NEXT: [[TMP24:%.*]] = call i32 @llvm.amdgcn.waterfall.readfirstlane.i32.i32(i32 [[TMP23]], i32 [[TMP15]]) +; CHECK-NEXT: [[TMP25:%.*]] = sext i32 [[TMP24]] to i64 +; CHECK-NEXT: [[TMP26:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP9]], i64 [[TMP25]] +; CHECK-NEXT: [[TMP27:%.*]] = load <8 x i32>, ptr addrspace(4) [[TMP26]], align 32, !invariant.load !10 +; CHECK-NEXT: [[TMP28:%.*]] = sext i32 [[TMP24]] to i64 +; CHECK-NEXT: [[TMP29:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP14]], i64 [[TMP28]] +; CHECK-NEXT: [[TMP30:%.*]] = load <4 x i32>, ptr addrspace(4) [[TMP29]], align 16, !invariant.load !10 +; CHECK-NEXT: [[TMP31:%.*]] = call reassoc nnan nsz arcp contract afn <4 x float> @llvm.amdgcn.image.sample.2d.v4f32.f32(i32 15, float 0.000000e+00, float 0.000000e+00, <8 x i32> [[TMP27]], <4 x i32> [[TMP30]], i1 false, i32 0, i32 0) +; CHECK-NEXT: [[TMP32:%.*]] = call reassoc nnan nsz arcp contract afn <4 x float> @llvm.amdgcn.waterfall.end.v4f32(i32 [[TMP23]], <4 x float> [[TMP31]]) +; CHECK-NEXT: call void @lgc.output.export.generic.i32.i32.v4f32(i32 0, i32 0, <4 x float> [[TMP32]]) #[[ATTR5:[0-9]+]] +; CHECK-NEXT: ret void +; diff --git a/lgc/test/scalarizationOfDescriptorLoadsTest9.ll b/lgc/test/scalarizationOfDescriptorLoadsTest9.ll new file mode 100644 index 0000000000..d9cb6429c2 --- /dev/null +++ b/lgc/test/scalarizationOfDescriptorLoadsTest9.ll @@ -0,0 +1,133 @@ +; NOTE: Assertions have been autogenerated by tool/update_llpc_test_checks.py UTC_ARGS: --tool lgc +; RUN: lgc -mcpu=gfx1010 -print-after=lgc-builder-replayer -o - %s 2>&1 | FileCheck --check-prefixes=CHECK %s +; ModuleID = 'lgcPipeline' +source_filename = "llpc_fragment_7" +target datalayout = "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-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-p32:32:32" +target triple = "amdgcn--amdpal" + +; Function Attrs: nounwind +define dllexport spir_func void @lgc.shader.FS.main() local_unnamed_addr #0 !spirv.ExecutionModel !8 !lgc.shaderstage !9 { +.entry: + %0 = call i32 (...) @lgc.create.read.generic.input.i32(i32 3, i32 0, i32 0, i32 0, i32 17, i32 poison) + %1 = call ptr addrspace(4) (...) @lgc.create.get.desc.ptr.p4(i32 1, i32 1, i64 0, i32 7) + %2 = call ptr addrspace(4) (...) @lgc.create.get.desc.ptr.p4(i32 2, i32 2, i64 0, i32 7) + br label %loop + +loop: + %phi.ind = phi i32 [ 0, %.entry], [ %ind, %loop] + %a = call i32 (...) @lgc.create.get.desc.stride.i32(i32 1, i32 1, i64 0, i32 7) + %b = call i32 (...) @lgc.create.get.desc.stride.i32(i32 2, i32 2, i64 0, i32 7) + %3 = mul i32 %phi.ind, %a + %4 = sext i32 %3 to i64 + %5 = getelementptr i8, ptr addrspace(4) %1, i64 %4 + %6 = mul i32 %phi.ind, %b + %7 = sext i32 %6 to i64 + %8 = getelementptr i8, ptr addrspace(4) %2, i64 %7 + %9 = load <4 x i32>, ptr addrspace(4) %8, align 16, !invariant.load !10 + %10 = load <8 x i32>, ptr addrspace(4) %5, align 32, !invariant.load !10 + %11 = call reassoc nnan nsz arcp contract afn <4 x float> (...) @lgc.create.image.sample.v4f32(i32 1, i32 24, <8 x i32> %10, <4 x i32> %9, i32 1, <2 x float> zeroinitializer) + call void (...) @lgc.create.write.generic.output(<4 x float> %11, i32 0, i32 0, i32 0, i32 0, i32 0, i32 poison) + %ind = add i32 %phi.ind, 1 + %cond = icmp ne i32 %ind, 1000 + br i1 %cond, label %loop, label %exit + +exit: + ret void +} + +declare spir_func void @spirv.NonUniform.i32(i32) local_unnamed_addr + +; Function Attrs: nounwind memory(none) +declare !lgc.create.opcode !11 ptr addrspace(4) @lgc.create.get.desc.ptr.p4(...) local_unnamed_addr #1 + +; Function Attrs: nounwind memory(none) +declare !lgc.create.opcode !12 i32 @lgc.create.get.desc.stride.i32(...) local_unnamed_addr #1 + +declare spir_func void @"spirv.NonUniform.s[s[p4,i32,i32,i32],s[p4,i32,i32]]"({ { ptr addrspace(4), i32, i32, i32 }, { ptr addrspace(4), i32, i32 } }) local_unnamed_addr + +declare spir_func void @"spirv.NonUniform.s[a3v8i32,s[v4i32,i32]]"({ [3 x <8 x i32>], { <4 x i32>, i32 } }) local_unnamed_addr + +; Function Attrs: nounwind willreturn memory(read) +declare !lgc.create.opcode !13 <4 x float> @lgc.create.image.sample.v4f32(...) local_unnamed_addr #2 + +; Function Attrs: nounwind willreturn memory(read) +declare !lgc.create.opcode !14 i32 @lgc.create.read.generic.input.i32(...) local_unnamed_addr #2 + +; Function Attrs: nounwind +declare !lgc.create.opcode !15 void @lgc.create.write.generic.output(...) local_unnamed_addr #3 + +attributes #0 = { nounwind "denormal-fp-math-f32"="preserve-sign" } +attributes #1 = { nounwind memory(none) } +attributes #2 = { nounwind willreturn memory(read) } +attributes #3 = { nounwind } + +!lgc.client = !{!0} +!lgc.unlinked = !{!1} +!lgc.options = !{!2} +!lgc.options.FS = !{!3} +!lgc.user.data.nodes = !{!4, !5} +!lgc.color.export.formats = !{!6} +!amdgpu.pal.metadata.msgpack = !{!7} + +!0 = !{!"Vulkan"} +!1 = !{i32 1} +!2 = !{i32 -158725823, i32 1419665388, i32 -1015833383, i32 -491143713, i32 1, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 1, i32 256, i32 256, i32 2, i32 1} +!3 = !{i32 -1822594139, i32 1920663194, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 64, i32 0, i32 0, i32 3, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 20, i32 1800, i32 0, i32 0, i32 1} +!4 = !{!"DescriptorTableVaPtr", i32 7, i32 64, i32 0, i32 1, i32 1} +!5 = !{!"DescriptorCombinedTexture", i32 3, i32 64, i32 0, i32 192, i64 0, i32 7, i32 12} +!6 = !{i32 14, i32 7, i32 0, i32 0, i32 15} +!7 = !{!"\82\B0amdpal.pipelines\91\83\B0.spill_threshold\CD\FF\FF\B0.user_data_limit\00\AF.xgl_cache_info\82\B3.128_bit_cache_hash\92\CF\E8\D2\98>j\B9B\94\CF2\DEF\BF\9Fx\BC1\AD.llpc_version\A470.1\AEamdpal.version\92\03\00"} +!8 = !{i32 4} +!9 = !{i32 6} +!10 = !{} +!11 = !{i32 56} +!12 = !{i32 55} +!13 = !{i32 61} +!14 = !{i32 71} +!15 = !{i32 74} + +; CHECK-LABEL: @lgc.shader.FS.main( +; CHECK-NEXT: .entry: +; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.amdgcn.s.getpc() +; CHECK-NEXT: [[TMP1:%.*]] = bitcast i64 [[TMP0]] to <2 x i32> +; CHECK-NEXT: [[TMP2:%.*]] = call i64 @llvm.amdgcn.s.getpc() +; CHECK-NEXT: [[TMP3:%.*]] = bitcast i64 [[TMP2]] to <2 x i32> +; CHECK-NEXT: [[TMP4:%.*]] = call i32 (...) @lgc.input.import.interpolated.i32(i1 false, i32 3, i32 0, i32 0, i32 poison, i32 1, i32 poison) +; CHECK-NEXT: [[TMP5:%.*]] = call i32 @lgc.load.user.data.i32(i32 0) +; CHECK-NEXT: [[TMP6:%.*]] = insertelement <2 x i32> [[TMP3]], i32 [[TMP5]], i64 0 +; CHECK-NEXT: [[TMP7:%.*]] = bitcast <2 x i32> [[TMP6]] to i64 +; CHECK-NEXT: [[TMP8:%.*]] = inttoptr i64 [[TMP7]] to ptr addrspace(4) +; CHECK-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP8]], i32 0 +; CHECK-NEXT: [[TMP10:%.*]] = call i32 @lgc.load.user.data.i32(i32 0) +; CHECK-NEXT: [[TMP11:%.*]] = insertelement <2 x i32> [[TMP1]], i32 [[TMP10]], i64 0 +; CHECK-NEXT: [[TMP12:%.*]] = bitcast <2 x i32> [[TMP11]] to i64 +; CHECK-NEXT: [[TMP13:%.*]] = inttoptr i64 [[TMP12]] to ptr addrspace(4) +; CHECK-NEXT: [[TMP14:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP13]], i32 32 +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: [[PHI_IND:%.*]] = phi i32 [ 0, [[DOTENTRY:%.*]] ], [ [[IND:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[TMP15:%.*]] = mul i32 [[PHI_IND]], 48 +; CHECK-NEXT: [[TMP16:%.*]] = sext i32 [[TMP15]] to i64 +; CHECK-NEXT: [[TMP17:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP9]], i64 [[TMP16]] +; CHECK-NEXT: [[TMP18:%.*]] = mul i32 [[PHI_IND]], 48 +; CHECK-NEXT: [[TMP19:%.*]] = sext i32 [[TMP18]] to i64 +; CHECK-NEXT: [[TMP20:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP14]], i64 [[TMP19]] +; CHECK-NEXT: [[TMP21:%.*]] = load <4 x i32>, ptr addrspace(4) [[TMP20]], align 16, !invariant.load !10 +; CHECK-NEXT: [[TMP22:%.*]] = load <8 x i32>, ptr addrspace(4) [[TMP17]], align 32, !invariant.load !10 +; CHECK-NEXT: [[TMP23:%.*]] = call i32 @llvm.amdgcn.waterfall.begin.i32(i32 0, i32 [[TMP15]]) +; CHECK-NEXT: [[TMP24:%.*]] = call i32 @llvm.amdgcn.waterfall.readfirstlane.i32.i32(i32 [[TMP23]], i32 [[TMP15]]) +; CHECK-NEXT: [[TMP25:%.*]] = sext i32 [[TMP24]] to i64 +; CHECK-NEXT: [[TMP26:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP9]], i64 [[TMP25]] +; CHECK-NEXT: [[TMP27:%.*]] = load <8 x i32>, ptr addrspace(4) [[TMP26]], align 32, !invariant.load !10 +; CHECK-NEXT: [[TMP28:%.*]] = sext i32 [[TMP24]] to i64 +; CHECK-NEXT: [[TMP29:%.*]] = getelementptr i8, ptr addrspace(4) [[TMP14]], i64 [[TMP28]] +; CHECK-NEXT: [[TMP30:%.*]] = load <4 x i32>, ptr addrspace(4) [[TMP29]], align 16, !invariant.load !10 +; CHECK-NEXT: [[TMP31:%.*]] = call reassoc nnan nsz arcp contract afn <4 x float> @llvm.amdgcn.image.sample.2d.v4f32.f32(i32 15, float 0.000000e+00, float 0.000000e+00, <8 x i32> [[TMP27]], <4 x i32> [[TMP30]], i1 false, i32 0, i32 0) +; CHECK-NEXT: [[TMP32:%.*]] = call reassoc nnan nsz arcp contract afn <4 x float> @llvm.amdgcn.waterfall.end.v4f32(i32 [[TMP23]], <4 x float> [[TMP31]]) +; CHECK-NEXT: call void @lgc.output.export.generic.i32.i32.v4f32(i32 0, i32 0, <4 x float> [[TMP32]]) #[[ATTR5:[0-9]+]] +; CHECK-NEXT: [[IND]] = add i32 [[PHI_IND]], 1 +; CHECK-NEXT: [[COND:%.*]] = icmp ne i32 [[IND]], 1000 +; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]] +; CHECK: exit: +; CHECK-NEXT: ret void +; diff --git a/llpc/test/shaderdb/core/OpTypeSampledImage_TestWaterfallScalarize_MultiBlock.frag b/llpc/test/shaderdb/core/OpTypeSampledImage_TestWaterfallScalarize_MultiBlock.frag index 8e1893653d..b88796da00 100644 --- a/llpc/test/shaderdb/core/OpTypeSampledImage_TestWaterfallScalarize_MultiBlock.frag +++ b/llpc/test/shaderdb/core/OpTypeSampledImage_TestWaterfallScalarize_MultiBlock.frag @@ -32,132 +32,129 @@ void main() // SHADERTEST-GFX-LABEL: {{^// LLPC}} pipeline patching results // SHADERTEST-GFX: %[[mul1:[0-9]+]] = mul i32 %{{.*}}, 48 -// SHADERTEST-GFX-NEXT: %[[sext1:[0-9]+]] = sext i32 %[[mul1]] to i64 -// SHADERTEST-GFX-NEXT: %[[gep1:[0-9]+]] = getelementptr i8, ptr addrspace(4) %{{.*}}, i64 %[[sext1]] -// SHADERTEST-GFX-NEXT: %[[gep2:[0-9]+]] = getelementptr i8, ptr addrspace(4) %{{.*}}, i64 %[[sext1]] -// SHADERTEST-GFX-NEXT: %[[load1:[0-9]+]] = load <4 x i32>, ptr addrspace(4) %[[gep2]], align 16 -// SHADERTEST-GFX-NEXT: %[[load2:[0-9]+]] = load <8 x i32>, ptr addrspace(4) %[[gep1]], align 32 // SHADERTEST-GFX-NEXT: %[[begin1:[0-9]+]] = call i32 @llvm.amdgcn.waterfall.begin.i32(i32 0, i32 %[[mul1]]) // SHADERTEST-GFX-NEXT: %[[readfirstlane1:[0-9]+]] = call i32 @llvm.amdgcn.waterfall.readfirstlane.i32.i32(i32 %[[begin1]], i32 %[[mul1]]) -// SHADERTEST-GFX-NEXT: %[[sext2:[0-9]+]] = sext i32 %[[readfirstlane1]] to i64 -// SHADERTEST-GFX-NEXT: %[[gep3:[0-9]+]] = getelementptr i8, ptr addrspace(4) %{{.*}}, i64 %[[sext2]] -// SHADERTEST-GFX-NEXT: %[[load3:[0-9]+]] = load <8 x i32>, ptr addrspace(4) %[[gep3]], align 32 -// SHADERTEST-GFX-NEXT: %[[extract1:[.a-z0-9]+]] = extractelement <8 x i32> %[[load3]], i64 3 +// SHADERTEST-GFX-NEXT: %[[sext1:[0-9]+]] = sext i32 %[[readfirstlane1]] to i64 +// SHADERTEST-GFX-NEXT: %[[gep1:[0-9]+]] = getelementptr i8, ptr addrspace(4) %{{.*}}, i64 %[[sext1]] +// SHADERTEST-GFX-NEXT: %[[load1:[0-9]+]] = load <8 x i32>, ptr addrspace(4) %[[gep1]], align 32 +// SHADERTEST-GFX-NEXT: %[[extract1:[.a-z0-9]+]] = extractelement <8 x i32> %[[load1]], i64 3 // SHADERTEST-GFX-NEXT: %[[and1:[0-9]+]] = and i32 %[[extract1]], 268435455 // SHADERTEST-GFX-NEXT: %[[cmp1:[0-9]+]] = icmp slt i32 %[[extract1]], 0 // SHADERTEST-GFX-NEXT: %[[select1:[0-9]+]] = select i1 %[[cmp1]], i32 %[[extract1]], i32 %[[and1]] -// SHADERTEST-GFX-NEXT: %[[insert1:[.a-z0-9]+]] = insertelement <8 x i32> %[[load3]], i32 %[[select1]], i64 3 -// SHADERTEST-GFX-NEXT: %[[shufflevector1:[0-9]+]] = shufflevector <8 x i32> %[[insert1]], <8 x i32> %[[load3]], <8 x i32> -// SHADERTEST-GFX-NEXT: %[[gep4:[0-9]+]] = getelementptr i8, ptr addrspace(4) %{{.*}}, i64 %[[sext2]] -// SHADERTEST-GFX-NEXT: %[[load4:[0-9]+]] = load <4 x i32>, ptr addrspace(4) %[[gep4]], align 16 -// SHADERTEST-GFX-NEXT: %[[image_call1:[0-9]+]] = call reassoc nnan nsz arcp contract afn <4 x float> @llvm.amdgcn.image.sample.2d.v4f32.f32(i32 15, float %{{.*}}, float %{{.*}}, <8 x i32> %[[shufflevector1]], <4 x i32> %[[load4]], i1 false, i32 0, i32 0) +// SHADERTEST-GFX-NEXT: %[[insert1:[.a-z0-9]+]] = insertelement <8 x i32> %[[load1]], i32 %[[select1]], i64 3 +// SHADERTEST-GFX-NEXT: %[[shufflevector1:[0-9]+]] = shufflevector <8 x i32> %[[insert1]], <8 x i32> %[[load1]], <8 x i32> +// SHADERTEST-GFX-NEXT: %[[gep2:[0-9]+]] = getelementptr i8, ptr addrspace(4) %{{.*}}, i64 %[[sext1]] +// SHADERTEST-GFX-NEXT: %[[load2:[0-9]+]] = load <4 x i32>, ptr addrspace(4) %[[gep2]], align 16 +// SHADERTEST-GFX-NEXT: %[[image_call1:[0-9]+]] = call reassoc nnan nsz arcp contract afn <4 x float> @llvm.amdgcn.image.sample.2d.v4f32.f32(i32 15, float %{{.*}}, float %{{.*}}, <8 x i32> %[[shufflevector1]], <4 x i32> %[[load2]], i1 false, i32 0, i32 0) // SHADERTEST-GFX-NEXT: %[[end1:[0-9]+]] = call reassoc nnan nsz arcp contract afn <4 x float> @llvm.amdgcn.waterfall.end.v4f32(i32 %[[begin1]], <4 x float> %[[image_call1]]) // // SHADERTEST-GFX-NEXT: %[[begin2:[0-9]+]] = call i32 @llvm.amdgcn.waterfall.begin.i32(i32 0, i32 %[[mul1]]) // SHADERTEST-GFX-NEXT: %[[readfirstlane2:[0-9]+]] = call i32 @llvm.amdgcn.waterfall.readfirstlane.i32.i32(i32 %[[begin2]], i32 %[[mul1]]) -// SHADERTEST-GFX-NEXT: %[[sext3:[0-9]+]] = sext i32 %[[readfirstlane2]] to i64 -// SHADERTEST-GFX-NEXT: %[[gep5:[0-9]+]] = getelementptr i8, ptr addrspace(4) %{{.*}}, i64 %[[sext3]] -// SHADERTEST-GFX-NEXT: %[[load5:[0-9]+]] = load <8 x i32>, ptr addrspace(4) %[[gep5]], align 32 -// SHADERTEST-GFX-NEXT: %[[extract2:[.a-z0-9]+]] = extractelement <8 x i32> %[[load5]], i64 3 +// SHADERTEST-GFX-NEXT: %[[sext2:[0-9]+]] = sext i32 %[[readfirstlane2]] to i64 +// SHADERTEST-GFX-NEXT: %[[gep3:[0-9]+]] = getelementptr i8, ptr addrspace(4) %{{.*}}, i64 %[[sext2]] +// SHADERTEST-GFX-NEXT: %[[load3:[0-9]+]] = load <8 x i32>, ptr addrspace(4) %[[gep3]], align 32 +// SHADERTEST-GFX-NEXT: %[[extract2:[.a-z0-9]+]] = extractelement <8 x i32> %[[load3]], i64 3 // SHADERTEST-GFX-NEXT: %[[and2:[0-9]+]] = and i32 %[[extract2]], 268435455 // SHADERTEST-GFX-NEXT: %[[cmp2:[0-9]+]] = icmp slt i32 %[[extract2]], 0 // SHADERTEST-GFX-NEXT: %[[select2:[0-9]+]] = select i1 %[[cmp2]], i32 %[[extract2]], i32 %[[and2]] -// SHADERTEST-GFX-NEXT: %[[insert2:[.a-z0-9]+]] = insertelement <8 x i32> %[[load5]], i32 %[[select2]], i64 3 -// SHADERTEST-GFX-NEXT: %[[shufflevector2:[0-9]+]] = shufflevector <8 x i32> %[[insert2]], <8 x i32> %[[load5]], <8 x i32> -// SHADERTEST-GFX-NEXT: %[[gep6:[0-9]+]] = getelementptr i8, ptr addrspace(4) %{{.*}}, i64 %[[sext3]] -// SHADERTEST-GFX-NEXT: %[[load6:[0-9]+]] = load <4 x i32>, ptr addrspace(4) %[[gep6]], align 16 -// SHADERTEST-GFX-NEXT: %[[image_call2:[0-9]+]] = call reassoc nnan nsz arcp contract afn <4 x float> @llvm.amdgcn.image.sample.2d.v4f32.f32(i32 15, float %{{.*}}, float %{{.*}}, <8 x i32> %[[shufflevector2]], <4 x i32> %[[load6]], i1 false, i32 0, i32 0) +// SHADERTEST-GFX-NEXT: %[[insert2:[.a-z0-9]+]] = insertelement <8 x i32> %[[load3]], i32 %[[select2]], i64 3 +// SHADERTEST-GFX-NEXT: %[[shufflevector2:[0-9]+]] = shufflevector <8 x i32> %[[insert2]], <8 x i32> %[[load3]], <8 x i32> +// SHADERTEST-GFX-NEXT: %[[gep4:[0-9]+]] = getelementptr i8, ptr addrspace(4) %{{.*}}, i64 %[[sext2]] +// SHADERTEST-GFX-NEXT: %[[load4:[0-9]+]] = load <4 x i32>, ptr addrspace(4) %[[gep4]], align 16 +// SHADERTEST-GFX-NEXT: %[[image_call2:[0-9]+]] = call reassoc nnan nsz arcp contract afn <4 x float> @llvm.amdgcn.image.sample.2d.v4f32.f32(i32 15, float %{{.*}}, float %{{.*}}, <8 x i32> %[[shufflevector2]], <4 x i32> %[[load4]], i1 false, i32 0, i32 0) // SHADERTEST-GFX-NEXT: %[[end2:[0-9]+]] = call reassoc nnan nsz arcp contract afn <4 x float> @llvm.amdgcn.waterfall.end.v4f32(i32 %[[begin2]], <4 x float> %[[image_call2]]) // // SHADERTEST-GFX: %[[begin3:[0-9]+]] = call i32 @llvm.amdgcn.waterfall.begin.i32(i32 0, i32 %[[mul1]]) -// SHADERTEST-GFX-NEXT: %[[readfirstlane3:[0-9]+]] = call <8 x i32> @llvm.amdgcn.waterfall.readfirstlane.v8i32.v8i32(i32 %[[begin3]], <8 x i32> %[[load2]]) -// SHADERTEST-GFX-NEXT: %[[extract3:[.a-z0-9]+]] = extractelement <8 x i32> %[[readfirstlane3]], i64 3 +// SHADERTEST-GFX-NEXT: %[[readfirstlane3:[0-9]+]] = call i32 @llvm.amdgcn.waterfall.readfirstlane.i32.i32(i32 %[[begin3]], i32 %[[mul1]]) +// SHADERTEST-GFX-NEXT: %[[sext3:[0-9]+]] = sext i32 %[[readfirstlane3]] to i64 +// SHADERTEST-GFX-NEXT: %[[gep5:[0-9]+]] = getelementptr i8, ptr addrspace(4) %{{.*}}, i64 %[[sext3]] +// SHADERTEST-GFX-NEXT: %[[load5:[0-9]+]] = load <8 x i32>, ptr addrspace(4) %[[gep5]], align 32 +// SHADERTEST-GFX-NEXT: %[[extract3:[.a-z0-9]+]] = extractelement <8 x i32> %[[load5]], i64 3 // SHADERTEST-GFX-NEXT: %[[and3:[0-9]+]] = and i32 %[[extract3]], 268435455 // SHADERTEST-GFX-NEXT: %[[cmp3:[0-9]+]] = icmp slt i32 %[[extract3]], 0 // SHADERTEST-GFX-NEXT: %[[select3:[0-9]+]] = select i1 %[[cmp3]], i32 %[[extract3]], i32 %[[and3]] -// SHADERTEST-GFX-NEXT: %[[insert3:[.a-z0-9]+]] = insertelement <8 x i32> %[[readfirstlane3]], i32 %[[select3]], i64 3 -// SHADERTEST-GFX-NEXT: %[[shufflevector3:[0-9]+]] = shufflevector <8 x i32> %[[insert3]], <8 x i32> %[[readfirstlane3]], <8 x i32> -// SHADERTEST-GFX-NEXT: %[[readfirstlane4:[0-9]+]] = call <4 x i32> @llvm.amdgcn.waterfall.readfirstlane.v4i32.v4i32(i32 %[[begin3]], <4 x i32> %[[load1]]) -// SHADERTEST-GFX-NEXT: [[image_call3:[0-9]+]] = call reassoc nnan nsz arcp contract afn <4 x float> @llvm.amdgcn.image.sample.2d.v4f32.f32(i32 15, float %{{.*}}, float %{{.*}}, <8 x i32> %[[shufflevector3]], <4 x i32> %[[readfirstlane4]], i1 false, i32 0, i32 0) +// SHADERTEST-GFX-NEXT: %[[insert3:[.a-z0-9]+]] = insertelement <8 x i32> %[[load5]], i32 %[[select3]], i64 3 +// SHADERTEST-GFX-NEXT: %[[shufflevector3:[0-9]+]] = shufflevector <8 x i32> %[[insert3]], <8 x i32> %[[load5]], <8 x i32> +// SHADERTEST-GFX-NEXT: %[[gep6:[0-9]+]] = getelementptr i8, ptr addrspace(4) %{{.*}}, i64 %[[sext3]] +// SHADERTEST-GFX-NEXT: %[[load6:[0-9]+]] = load <4 x i32>, ptr addrspace(4) %[[gep6]], align 16 +// SHADERTEST-GFX-NEXT: [[image_call3:[0-9]+]] = call reassoc nnan nsz arcp contract afn <4 x float> @llvm.amdgcn.image.sample.2d.v4f32.f32(i32 15, float %{{.*}}, float %{{.*}}, <8 x i32> %[[shufflevector3]], <4 x i32> %[[load6]], i1 false, i32 0, i32 0) // SHADERTEST-GFX-NEXT: %[[end3:[0-9]+]] = call reassoc nnan nsz arcp contract afn <4 x float> @llvm.amdgcn.waterfall.end.v4f32(i32 %[[begin3]], <4 x float> %[[image_call3]]) // SHADERTEST-GFX: AMDLLPC SUCCESS // // SHADERTEST-GFX_10_3_0-LABEL: {{^// LLPC}} pipeline patching results // SHADERTEST-GFX_10_3_0: %[[mul1:[0-9]+]] = mul i32 %{{.*}}, 48 -// SHADERTEST-GFX_10_3_0-NEXT: %[[sext1:[0-9]+]] = sext i32 %[[mul1]] to i64 -// SHADERTEST-GFX_10_3_0-NEXT: %[[gep1:[0-9]+]] = getelementptr i8, ptr addrspace(4) %{{.*}}, i64 %[[sext1]] -// SHADERTEST-GFX_10_3_0-NEXT: %[[gep2:[0-9]+]] = getelementptr i8, ptr addrspace(4) %{{.*}}, i64 %[[sext1]] -// SHADERTEST-GFX_10_3_0-NEXT: %[[load1:[0-9]+]] = load <4 x i32>, ptr addrspace(4) %[[gep2]], align 16 -// SHADERTEST-GFX_10_3_0-NEXT: %[[load2:[0-9]+]] = load <8 x i32>, ptr addrspace(4) %[[gep1]], align 32 // SHADERTEST-GFX_10_3_0-NEXT: %[[begin1:[0-9]+]] = call i32 @llvm.amdgcn.waterfall.begin.i32(i32 0, i32 %[[mul1]]) // SHADERTEST-GFX_10_3_0-NEXT: %[[readfirstlane1:[0-9]+]] = call i32 @llvm.amdgcn.waterfall.readfirstlane.i32.i32(i32 %[[begin1]], i32 %[[mul1]]) -// SHADERTEST-GFX_10_3_0-NEXT: %[[sext2:[0-9]+]] = sext i32 %[[readfirstlane1]] to i64 +// SHADERTEST-GFX_10_3_0-NEXT: %[[sext1:[0-9]+]] = sext i32 %[[readfirstlane1]] to i64 +// SHADERTEST-GFX_10_3_0-NEXT: %[[gep1:[0-9]+]] = getelementptr i8, ptr addrspace(4) %{{.*}}, i64 %[[sext1]] +// SHADERTEST-GFX_10_3_0-NEXT: %[[load1:[0-9]+]] = load <8 x i32>, ptr addrspace(4) %[[gep1]], align 32 +// SHADERTEST-GFX_10_3_0-NEXT: %[[gep2:[0-9]+]] = getelementptr i8, ptr addrspace(4) %{{.*}}, i64 %[[sext1]] +// SHADERTEST-GFX_10_3_0-NEXT: %[[load2:[0-9]+]] = load <4 x i32>, ptr addrspace(4) %[[gep2]], align 16 +// SHADERTEST-GFX_10_3_0-NEXT: %[[image_call1:[0-9]+]] = call reassoc nnan nsz arcp contract afn <4 x float> @llvm.amdgcn.image.sample.2d.v4f32.f32(i32 15, float %{{.*}}, float %{{.*}}, <8 x i32> %[[load1]], <4 x i32> %[[load2]], i1 false, i32 0, i32 0) +// SHADERTEST-GFX_10_3_0-NEXT: %[[end1:[0-9]+]] = call reassoc nnan nsz arcp contract afn <4 x float> @llvm.amdgcn.waterfall.end.v4f32(i32 %[[begin1]], <4 x float> %[[image_call1]]) +// +// SHADERTEST-GFX_10_3_0-NEXT: %[[begin2:[0-9]+]] = call i32 @llvm.amdgcn.waterfall.begin.i32(i32 0, i32 %[[mul1]]) +// SHADERTEST-GFX_10_3_0-NEXT: %[[readfirstlane2:[0-9]+]] = call i32 @llvm.amdgcn.waterfall.readfirstlane.i32.i32(i32 %[[begin2]], i32 %[[mul1]]) +// SHADERTEST-GFX_10_3_0-NEXT: %[[sext2:[0-9]+]] = sext i32 %[[readfirstlane2]] to i64 // SHADERTEST-GFX_10_3_0-NEXT: %[[gep3:[0-9]+]] = getelementptr i8, ptr addrspace(4) %{{.*}}, i64 %[[sext2]] // SHADERTEST-GFX_10_3_0-NEXT: %[[load3:[0-9]+]] = load <8 x i32>, ptr addrspace(4) %[[gep3]], align 32 // SHADERTEST-GFX_10_3_0-NEXT: %[[gep4:[0-9]+]] = getelementptr i8, ptr addrspace(4) %{{.*}}, i64 %[[sext2]] // SHADERTEST-GFX_10_3_0-NEXT: %[[load4:[0-9]+]] = load <4 x i32>, ptr addrspace(4) %[[gep4]], align 16 -// SHADERTEST-GFX_10_3_0-NEXT: %[[image_call1:[0-9]+]] = call reassoc nnan nsz arcp contract afn <4 x float> @llvm.amdgcn.image.sample.2d.v4f32.f32(i32 15, float %{{.*}}, float %{{.*}}, <8 x i32> %[[load3]], <4 x i32> %[[load4]], i1 false, i32 0, i32 0) -// SHADERTEST-GFX_10_3_0-NEXT: %[[end1:[0-9]+]] = call reassoc nnan nsz arcp contract afn <4 x float> @llvm.amdgcn.waterfall.end.v4f32(i32 %[[begin1]], <4 x float> %[[image_call1]]) +// SHADERTEST-GFX_10_3_0-NEXT: %[[image_call2:[0-9]+]] = call reassoc nnan nsz arcp contract afn <4 x float> @llvm.amdgcn.image.sample.2d.v4f32.f32(i32 15, float %{{.*}}, float %{{.*}}, <8 x i32> %[[load3]], <4 x i32> %[[load4]], i1 false, i32 0, i32 0) +// SHADERTEST-GFX_10_3_0-NEXT: %[[end2:[0-9]+]] = call reassoc nnan nsz arcp contract afn <4 x float> @llvm.amdgcn.waterfall.end.v4f32(i32 %[[begin2]], <4 x float> %[[image_call2]]) // -// SHADERTEST-GFX_10_3_0-NEXT: %[[begin2:[0-9]+]] = call i32 @llvm.amdgcn.waterfall.begin.i32(i32 0, i32 %[[mul1]]) -// SHADERTEST-GFX_10_3_0-NEXT: %[[readfirstlane2:[0-9]+]] = call i32 @llvm.amdgcn.waterfall.readfirstlane.i32.i32(i32 %[[begin2]], i32 %[[mul1]]) -// SHADERTEST-GFX_10_3_0-NEXT: %[[sext3:[0-9]+]] = sext i32 %[[readfirstlane2]] to i64 +// SHADERTEST-GFX_10_3_0: %[[begin3:[0-9]+]] = call i32 @llvm.amdgcn.waterfall.begin.i32(i32 0, i32 %[[mul1]]) +// SHADERTEST-GFX_10_3_0-NEXT: %[[readfirstlane3:[0-9]+]] = call i32 @llvm.amdgcn.waterfall.readfirstlane.i32.i32(i32 %[[begin3]], i32 %[[mul1]]) +// SHADERTEST-GFX_10_3_0-NEXT: %[[sext3:[0-9]+]] = sext i32 %[[readfirstlane3]] to i64 // SHADERTEST-GFX_10_3_0-NEXT: %[[gep5:[0-9]+]] = getelementptr i8, ptr addrspace(4) %{{.*}}, i64 %[[sext3]] // SHADERTEST-GFX_10_3_0-NEXT: %[[load5:[0-9]+]] = load <8 x i32>, ptr addrspace(4) %[[gep5]], align 32 // SHADERTEST-GFX_10_3_0-NEXT: %[[gep6:[0-9]+]] = getelementptr i8, ptr addrspace(4) %{{.*}}, i64 %[[sext3]] // SHADERTEST-GFX_10_3_0-NEXT: %[[load6:[0-9]+]] = load <4 x i32>, ptr addrspace(4) %[[gep6]], align 16 -// SHADERTEST-GFX_10_3_0-NEXT: %[[image_call2:[0-9]+]] = call reassoc nnan nsz arcp contract afn <4 x float> @llvm.amdgcn.image.sample.2d.v4f32.f32(i32 15, float %{{.*}}, float %{{.*}}, <8 x i32> %[[load5]], <4 x i32> %[[load6]], i1 false, i32 0, i32 0) -// SHADERTEST-GFX_10_3_0-NEXT: %[[end2:[0-9]+]] = call reassoc nnan nsz arcp contract afn <4 x float> @llvm.amdgcn.waterfall.end.v4f32(i32 %[[begin2]], <4 x float> %[[image_call2]]) -// -// SHADERTEST-GFX_10_3_0: %[[begin3:[0-9]+]] = call i32 @llvm.amdgcn.waterfall.begin.i32(i32 0, i32 %[[mul1]]) -// SHADERTEST-GFX_10_3_0-NEXT: %[[readfirstlane3:[0-9]+]] = call <8 x i32> @llvm.amdgcn.waterfall.readfirstlane.v8i32.v8i32(i32 %[[begin3]], <8 x i32> %[[load2]]) -// SHADERTEST-GFX_10_3_0-NEXT: %[[readfirstlane4:[0-9]+]] = call <4 x i32> @llvm.amdgcn.waterfall.readfirstlane.v4i32.v4i32(i32 %[[begin3]], <4 x i32> %[[load1]]) -// SHADERTEST-GFX_10_3_0-NEXT: [[image_call3:[0-9]+]] = call reassoc nnan nsz arcp contract afn <4 x float> @llvm.amdgcn.image.sample.2d.v4f32.f32(i32 15, float %{{.*}}, float %{{.*}}, <8 x i32> %[[readfirstlane3]], <4 x i32> %[[readfirstlane4]], i1 false, i32 0, i32 0) +// SHADERTEST-GFX_10_3_0-NEXT: [[image_call3:[0-9]+]] = call reassoc nnan nsz arcp contract afn <4 x float> @llvm.amdgcn.image.sample.2d.v4f32.f32(i32 15, float %{{.*}}, float %{{.*}}, <8 x i32> %[[load5]], <4 x i32> %[[load6]], i1 false, i32 0, i32 0) // SHADERTEST-GFX_10_3_0-NEXT: %[[end3:[0-9]+]] = call reassoc nnan nsz arcp contract afn <4 x float> @llvm.amdgcn.waterfall.end.v4f32(i32 %[[begin3]], <4 x float> %[[image_call3]]) // SHADERTEST-GFX_10_3_0: AMDLLPC SUCCESS // // SHADERTEST-GFX_10_3_2-LABEL: {{^// LLPC}} pipeline patching results // SHADERTEST-GFX_10_3_2: %[[mul1:[0-9]+]] = mul i32 %{{.*}}, 48 -// SHADERTEST-GFX_10_3_2-NEXT: %[[sext1:[0-9]+]] = sext i32 %[[mul1]] to i64 -// SHADERTEST-GFX_10_3_2-NEXT: %[[gep1:[0-9]+]] = getelementptr i8, ptr addrspace(4) %{{.*}}, i64 %[[sext1]] -// SHADERTEST-GFX_10_3_2-NEXT: %[[gep2:[0-9]+]] = getelementptr i8, ptr addrspace(4) %{{.*}}, i64 %[[sext1]] -// SHADERTEST-GFX_10_3_2-NEXT: %[[load1:[0-9]+]] = load <4 x i32>, ptr addrspace(4) %[[gep2]], align 16 -// SHADERTEST-GFX_10_3_2-NEXT: %[[load2:[0-9]+]] = load <8 x i32>, ptr addrspace(4) %[[gep1]], align 32 // SHADERTEST-GFX_10_3_2-NEXT: %[[begin1:[0-9]+]] = call i32 @llvm.amdgcn.waterfall.begin.i32(i32 0, i32 %[[mul1]]) // SHADERTEST-GFX_10_3_2-NEXT: %[[readfirstlane1:[0-9]+]] = call i32 @llvm.amdgcn.waterfall.readfirstlane.i32.i32(i32 %[[begin1]], i32 %[[mul1]]) -// SHADERTEST-GFX_10_3_2-NEXT: %[[sext2:[0-9]+]] = sext i32 %[[readfirstlane1]] to i64 -// SHADERTEST-GFX_10_3_2-NEXT: %[[gep3:[0-9]+]] = getelementptr i8, ptr addrspace(4) %{{.*}}, i64 %[[sext2]] -// SHADERTEST-GFX_10_3_2-NEXT: %[[load3:[0-9]+]] = load <8 x i32>, ptr addrspace(4) %[[gep3]], align 32 -// SHADERTEST-GFX_10_3_2-NEXT: %[[extract1:[.a-z0-9]+]] = extractelement <8 x i32> %[[load3]], i64 6 +// SHADERTEST-GFX_10_3_2-NEXT: %[[sext1:[0-9]+]] = sext i32 %[[readfirstlane1]] to i64 +// SHADERTEST-GFX_10_3_2-NEXT: %[[gep1:[0-9]+]] = getelementptr i8, ptr addrspace(4) %{{.*}}, i64 %[[sext1]] +// SHADERTEST-GFX_10_3_2-NEXT: %[[load1:[0-9]+]] = load <8 x i32>, ptr addrspace(4) %[[gep1]], align 32 +// SHADERTEST-GFX_10_3_2-NEXT: %[[extract1:[.a-z0-9]+]] = extractelement <8 x i32> %[[load1]], i64 6 // SHADERTEST-GFX_10_3_2-NEXT: %[[and1:[0-9]+]] = and i32 %[[extract1]], -1048577 -// SHADERTEST-GFX_10_3_2-NEXT: %[[insert1:[.a-z0-9]+]] = insertelement <8 x i32> %[[load3]], i32 %[[and1]], i64 6 -// SHADERTEST-GFX_10_3_2-NEXT: %[[shufflevector1:[0-9]+]] = shufflevector <8 x i32> %[[insert1]], <8 x i32> %[[load3]], <8 x i32> -// SHADERTEST-GFX_10_3_2-NEXT: %[[gep4:[0-9]+]] = getelementptr i8, ptr addrspace(4) %{{.*}}, i64 %[[sext2]] -// SHADERTEST-GFX_10_3_2-NEXT: %[[load4:[0-9]+]] = load <4 x i32>, ptr addrspace(4) %[[gep4]], align 16 -// SHADERTEST-GFX_10_3_2-NEXT: %[[image_call1:[0-9]+]] = call reassoc nnan nsz arcp contract afn <4 x float> @llvm.amdgcn.image.sample.2d.v4f32.f32(i32 15, float %{{.*}}, float %{{.*}}, <8 x i32> %[[shufflevector1]], <4 x i32> %[[load4]], i1 false, i32 0, i32 0) +// SHADERTEST-GFX_10_3_2-NEXT: %[[insert1:[.a-z0-9]+]] = insertelement <8 x i32> %[[load1]], i32 %[[and1]], i64 6 +// SHADERTEST-GFX_10_3_2-NEXT: %[[shufflevector1:[0-9]+]] = shufflevector <8 x i32> %[[insert1]], <8 x i32> %[[load1]], <8 x i32> +// SHADERTEST-GFX_10_3_2-NEXT: %[[gep2:[0-9]+]] = getelementptr i8, ptr addrspace(4) %{{.*}}, i64 %[[sext1]] +// SHADERTEST-GFX_10_3_2-NEXT: %[[load2:[0-9]+]] = load <4 x i32>, ptr addrspace(4) %[[gep2]], align 16 +// SHADERTEST-GFX_10_3_2-NEXT: %[[image_call1:[0-9]+]] = call reassoc nnan nsz arcp contract afn <4 x float> @llvm.amdgcn.image.sample.2d.v4f32.f32(i32 15, float %{{.*}}, float %{{.*}}, <8 x i32> %[[shufflevector1]], <4 x i32> %[[load2]], i1 false, i32 0, i32 0) // SHADERTEST-GFX_10_3_2-NEXT: %[[end1:[0-9]+]] = call reassoc nnan nsz arcp contract afn <4 x float> @llvm.amdgcn.waterfall.end.v4f32(i32 %[[begin1]], <4 x float> %[[image_call1]]) // // SHADERTEST-GFX_10_3_2-NEXT: %[[begin2:[0-9]+]] = call i32 @llvm.amdgcn.waterfall.begin.i32(i32 0, i32 %[[mul1]]) // SHADERTEST-GFX_10_3_2-NEXT: %[[readfirstlane2:[0-9]+]] = call i32 @llvm.amdgcn.waterfall.readfirstlane.i32.i32(i32 %[[begin2]], i32 %[[mul1]]) -// SHADERTEST-GFX_10_3_2-NEXT: %[[sext3:[0-9]+]] = sext i32 %[[readfirstlane2]] to i64 +// SHADERTEST-GFX_10_3_2-NEXT: %[[sext2:[0-9]+]] = sext i32 %[[readfirstlane2]] to i64 +// SHADERTEST-GFX_10_3_2-NEXT: %[[gep3:[0-9]+]] = getelementptr i8, ptr addrspace(4) %{{.*}}, i64 %[[sext2]] +// SHADERTEST-GFX_10_3_2-NEXT: %[[load3:[0-9]+]] = load <8 x i32>, ptr addrspace(4) %[[gep3]], align 32 +// SHADERTEST-GFX_10_3_2-NEXT: %[[extract2:[.a-z0-9]+]] = extractelement <8 x i32> %[[load3]], i64 6 +// SHADERTEST-GFX_10_3_2-NEXT: %[[and2:[0-9]+]] = and i32 %[[extract2]], -1048577 +// SHADERTEST-GFX_10_3_2-NEXT: %[[insert2:[.a-z0-9]+]] = insertelement <8 x i32> %[[load3]], i32 %[[and2]], i64 6 +// SHADERTEST-GFX_10_3_2-NEXT: %[[shufflevector2:[0-9]+]] = shufflevector <8 x i32> %[[insert2]], <8 x i32> %[[load3]], <8 x i32> +// SHADERTEST-GFX_10_3_2-NEXT: %[[gep4:[0-9]+]] = getelementptr i8, ptr addrspace(4) %{{.*}}, i64 %[[sext2]] +// SHADERTEST-GFX_10_3_2-NEXT: %[[load4:[0-9]+]] = load <4 x i32>, ptr addrspace(4) %[[gep4]], align 16 +// SHADERTEST-GFX_10_3_2-NEXT: %[[image_call2:[0-9]+]] = call reassoc nnan nsz arcp contract afn <4 x float> @llvm.amdgcn.image.sample.2d.v4f32.f32(i32 15, float %{{.*}}, float %{{.*}}, <8 x i32> %[[shufflevector2]], <4 x i32> %[[load4]], i1 false, i32 0, i32 0) +// SHADERTEST-GFX_10_3_2-NEXT: %[[end2:[0-9]+]] = call reassoc nnan nsz arcp contract afn <4 x float> @llvm.amdgcn.waterfall.end.v4f32(i32 %[[begin2]], <4 x float> %[[image_call2]]) +// +// SHADERTEST-GFX_10_3_2: %[[begin3:[0-9]+]] = call i32 @llvm.amdgcn.waterfall.begin.i32(i32 0, i32 %[[mul1]]) +// SHADERTEST-GFX_10_3_2-NEXT: %[[readfirstlane3:[0-9]+]] = call i32 @llvm.amdgcn.waterfall.readfirstlane.i32.i32(i32 %[[begin3]], i32 %[[mul1]]) +// SHADERTEST-GFX_10_3_2-NEXT: %[[sext3:[0-9]+]] = sext i32 %[[readfirstlane3]] to i64 // SHADERTEST-GFX_10_3_2-NEXT: %[[gep5:[0-9]+]] = getelementptr i8, ptr addrspace(4) %{{.*}}, i64 %[[sext3]] // SHADERTEST-GFX_10_3_2-NEXT: %[[load5:[0-9]+]] = load <8 x i32>, ptr addrspace(4) %[[gep5]], align 32 -// SHADERTEST-GFX_10_3_2-NEXT: %[[extract1:[.a-z0-9]+]] = extractelement <8 x i32> %[[load5]], i64 6 -// SHADERTEST-GFX_10_3_2-NEXT: %[[and1:[0-9]+]] = and i32 %[[extract1]], -1048577 -// SHADERTEST-GFX_10_3_2-NEXT: %[[insert1:[.a-z0-9]+]] = insertelement <8 x i32> %[[load5]], i32 %[[and1]], i64 6 -// SHADERTEST-GFX_10_3_2-NEXT: %[[shufflevector1:[0-9]+]] = shufflevector <8 x i32> %[[insert1]], <8 x i32> %[[load5]], <8 x i32> +// SHADERTEST-GFX_10_3_2-NEXT: %[[extract3:[.a-z0-9]+]] = extractelement <8 x i32> %[[load5]], i64 6 +// SHADERTEST-GFX_10_3_2-NEXT: %[[and3:[0-9]+]] = and i32 %[[extract3]], -1048577 +// SHADERTEST-GFX_10_3_2-NEXT: %[[insert3:[.a-z0-9]+]] = insertelement <8 x i32> %[[load5]], i32 %[[and3]], i64 6 +// SHADERTEST-GFX_10_3_2-NEXT: %[[shufflevector3:[0-9]+]] = shufflevector <8 x i32> %[[insert3]], <8 x i32> %[[load5]], <8 x i32> // SHADERTEST-GFX_10_3_2-NEXT: %[[gep6:[0-9]+]] = getelementptr i8, ptr addrspace(4) %{{.*}}, i64 %[[sext3]] // SHADERTEST-GFX_10_3_2-NEXT: %[[load6:[0-9]+]] = load <4 x i32>, ptr addrspace(4) %[[gep6]], align 16 -// SHADERTEST-GFX_10_3_2-NEXT: %[[image_call2:[0-9]+]] = call reassoc nnan nsz arcp contract afn <4 x float> @llvm.amdgcn.image.sample.2d.v4f32.f32(i32 15, float %{{.*}}, float %{{.*}}, <8 x i32> %[[shufflevector1]], <4 x i32> %[[load6]], i1 false, i32 0, i32 0) -// SHADERTEST-GFX_10_3_2-NEXT: %[[end2:[0-9]+]] = call reassoc nnan nsz arcp contract afn <4 x float> @llvm.amdgcn.waterfall.end.v4f32(i32 %[[begin2]], <4 x float> %[[image_call2]]) -// -// SHADERTEST-GFX_10_3_2: %[[extract2:[.a-z0-9]+]] = extractelement <8 x i32> %[[load2]], i64 6 -// SHADERTEST-GFX_10_3_2: %[[and2:[0-9]+]] = and i32 %[[extract2]], -1048577 -// SHADERTEST-GFX_10_3_2-NEXT: %[[insert2:[.a-z0-9]+]] = insertelement <8 x i32> %[[load2]], i32 %[[and2]], i64 6 -// SHADERTEST-GFX_10_3_2-NEXT: %[[shufflevector2:[0-9]+]] = shufflevector <8 x i32> %[[insert2]], <8 x i32> %[[load2]], <8 x i32> -// SHADERTEST-GFX_10_3_2: %[[begin3:[0-9]+]] = call i32 @llvm.amdgcn.waterfall.begin.i32(i32 0, i32 %[[mul1]]) -// SHADERTEST-GFX_10_3_2-NEXT: %[[readfirstlane3:[0-9]+]] = call <8 x i32> @llvm.amdgcn.waterfall.readfirstlane.v8i32.v8i32(i32 %[[begin3]], <8 x i32> %[[shufflevector2]]) -// SHADERTEST-GFX_10_3_2-NEXT: %[[readfirstlane4:[0-9]+]] = call <4 x i32> @llvm.amdgcn.waterfall.readfirstlane.v4i32.v4i32(i32 %[[begin3]], <4 x i32> %[[load1]]) -// SHADERTEST-GFX_10_3_2-NEXT: [[image_call3:[0-9]+]] = call reassoc nnan nsz arcp contract afn <4 x float> @llvm.amdgcn.image.sample.2d.v4f32.f32(i32 15, float %{{.*}}, float %{{.*}}, <8 x i32> %[[readfirstlane3]], <4 x i32> %[[readfirstlane4]], i1 false, i32 0, i32 0) +// SHADERTEST-GFX_10_3_2-NEXT: [[image_call3:[0-9]+]] = call reassoc nnan nsz arcp contract afn <4 x float> @llvm.amdgcn.image.sample.2d.v4f32.f32(i32 15, float %{{.*}}, float %{{.*}}, <8 x i32> %[[shufflevector3]], <4 x i32> %[[load6]], i1 false, i32 0, i32 0) // SHADERTEST-GFX_10_3_2-NEXT: %[[end3:[0-9]+]] = call reassoc nnan nsz arcp contract afn <4 x float> @llvm.amdgcn.waterfall.end.v4f32(i32 %[[begin3]], <4 x float> %[[image_call3]]) // SHADERTEST-GFX_10_3_2: AMDLLPC SUCCESS