From f875d3f5ba9c1ddc6aa9a0960efd5ab27ae4e4c9 Mon Sep 17 00:00:00 2001 From: Yong He Date: Wed, 9 Aug 2023 20:11:09 -0700 Subject: Support implciit casted swizzled lvalue. (#3077) * Support implciit casted swizzled lvalue. * Fix warnings. * Fix. * fix comment. * Prefer mangled linkage name for global params. * Update tests. --------- Co-authored-by: Yong He --- source/slang/slang-check-constraint.cpp | 17 +- source/slang/slang-check-conversion.cpp | 15 +- source/slang/slang-check-impl.h | 2 + source/slang/slang-emit-c-like.cpp | 2 +- source/slang/slang-ir-lower-l-value-cast.cpp | 28 +- source/slang/slang-ir-ssa.cpp | 11 +- source/slang/slang-lower-to-ir.cpp | 95 +++- tests/bugs/gh-3075.slang | 15 + tests/bugs/gh-3075.slang.expected.txt | 2 + tests/bugs/implicit-cast.slang | 18 + tests/bugs/implicit-cast.slang.expected.txt | 1 + .../hit-object-make-hit.slang.1.expected | 2 +- .../hit-object-reorder-thread.slang.1.expected | 2 +- .../hit-object-reorder-thread.slang.expected | 617 ++++----------------- .../hit-object-trace-motion-ray.slang.1.expected | 2 +- .../hit-object-trace-ray.slang.1.expected | 2 +- 16 files changed, 259 insertions(+), 572 deletions(-) create mode 100644 tests/bugs/gh-3075.slang create mode 100644 tests/bugs/gh-3075.slang.expected.txt create mode 100644 tests/bugs/implicit-cast.slang create mode 100644 tests/bugs/implicit-cast.slang.expected.txt diff --git a/source/slang/slang-check-constraint.cpp b/source/slang/slang-check-constraint.cpp index b9d33a1c1..d66bf35cc 100644 --- a/source/slang/slang-check-constraint.cpp +++ b/source/slang/slang-check-constraint.cpp @@ -186,20 +186,15 @@ namespace Slang { if (auto rightBasic = as(right)) { - auto leftFlavor = leftBasic->getBaseType(); - auto rightFlavor = rightBasic->getBaseType(); + auto costConvertRightToLeft = getConversionCost(leftBasic, rightBasic); + auto costConvertLeftToRight = getConversionCost(rightBasic, leftBasic); - // TODO(tfoley): Need a special-case rule here that if - // either operand is of type `half`, then we promote - // to at least `float` - - // Return the one that had higher rank... - if (leftFlavor > rightFlavor) - return left; + // Return the one that had lower conversion cost. + if (costConvertRightToLeft > costConvertLeftToRight) + return right; else { - SLANG_ASSERT(rightFlavor > leftFlavor); // equality was handles at the top of this function - return right; + return left; } } diff --git a/source/slang/slang-check-conversion.cpp b/source/slang/slang-check-conversion.cpp index d89808c3d..09a783fb4 100644 --- a/source/slang/slang-check-conversion.cpp +++ b/source/slang/slang-check-conversion.cpp @@ -1360,15 +1360,20 @@ namespace Slang Type* toType, Type* fromType) { - // Can we convert at all? - ConversionCost conversionCost; - if(!canCoerce(toType, fromType, nullptr, &conversionCost)) - return false; + auto conversionCost = getConversionCost(toType, fromType); // Is the conversion cheap enough to be done implicitly? - if(conversionCost >= kConversionCost_GeneralConversion) + if (conversionCost >= kConversionCost_GeneralConversion) return false; return true; } + + ConversionCost SemanticsVisitor::getConversionCost(Type* toType, Type* fromType) + { + ConversionCost conversionCost = kConversionCost_Impossible; + if (!canCoerce(toType, fromType, nullptr, &conversionCost)) + return kConversionCost_Impossible; + return conversionCost; + } } diff --git a/source/slang/slang-check-impl.h b/source/slang/slang-check-impl.h index 88f1e2975..6cb719e43 100644 --- a/source/slang/slang-check-impl.h +++ b/source/slang/slang-check-impl.h @@ -1911,6 +1911,8 @@ namespace Slang Type* toType, Type* fromType); + ConversionCost getConversionCost(Type* toType, Type* fromType); + Type* _tryJoinTypeWithInterface( Type* type, Type* interfaceType); diff --git a/source/slang/slang-emit-c-like.cpp b/source/slang/slang-emit-c-like.cpp index 5bd57e81c..e2faba808 100644 --- a/source/slang/slang-emit-c-like.cpp +++ b/source/slang/slang-emit-c-like.cpp @@ -951,7 +951,7 @@ String CLikeSourceEmitter::generateName(IRInst* inst) // Just use the linkages mangled name directly. return externCppDecoration->getName(); } - + // If we have a name hint on the instruction, then we will try to use that // to provide the basis for the actual name in the output code. if(auto nameHintDecoration = inst->findDecoration()) diff --git a/source/slang/slang-ir-lower-l-value-cast.cpp b/source/slang/slang-ir-lower-l-value-cast.cpp index cd03d2bd5..aca58cef3 100644 --- a/source/slang/slang-ir-lower-l-value-cast.cpp +++ b/source/slang/slang-ir-lower-l-value-cast.cpp @@ -166,15 +166,10 @@ struct LValueCastLoweringContext // convert in. // Okay we are going to replace the implicit casts with temporaries around call sites/uses. - List useSites; + List useSites; for (auto use = castInst->firstUse; use; use = use->nextUse) { - auto useSite = use->getUser(); - - if (useSites.indexOf(useSite) < 0) - { - useSites.add(useSite); - } + useSites.add(use); } // If there is a name hint on the source, we'll copy it over to the temporaries @@ -187,7 +182,8 @@ struct LValueCastLoweringContext for (auto useSite : useSites) { - builder.setInsertBefore(useSite); + auto user = useSite->getUser(); + builder.setInsertBefore(user); auto tmpVar = builder.emitVar(toValueType); if (nameHintDecoration) @@ -196,27 +192,17 @@ struct LValueCastLoweringContext } // If it's inout we convert via cast whats in the castOperand - if (castInst->getOp() == kIROp_InOutImplicitCast) + if (castInst->getOp() == kIROp_InOutImplicitCast && user->getOp() != kIROp_Store) { builder.emitStore(tmpVar, builder.emitCast(toValueType, builder.emitLoad(castOperand))); } // Convert the temporary back to the original location - builder.setInsertAfter(useSite); + builder.setInsertAfter(user); builder.emitStore(castOperand, builder.emitCast(fromValueType, builder.emitLoad(tmpVar))); // Go through all of the operands of the use inst relacing, with the temporary - const auto operandCount = Count(useSite->getOperandCount()); - auto operands = useSite->getOperands(); - - for (Index i = 0; i < operandCount; ++i) - { - auto& callSiteOperand = operands[i]; - if(callSiteOperand.get() == castInst) - { - callSiteOperand.set(tmpVar); - } - } + builder.replaceOperand(useSite, tmpVar); } // When we are done we can destroy the inst diff --git a/source/slang/slang-ir-ssa.cpp b/source/slang/slang-ir-ssa.cpp index 48cf2976f..18eba677e 100644 --- a/source/slang/slang-ir-ssa.cpp +++ b/source/slang/slang-ir-ssa.cpp @@ -379,11 +379,18 @@ static void cloneRelevantDecorations( break; case kIROp_PreciseDecoration: - case kIROp_NameHintDecoration: // Copy these decorations if the target doesn't already have them, // but don't make duplicate decorations on the target. // - if( !val->findDecorationImpl(decoration->getOp()) ) + if (!val->findDecorationImpl(decoration->getOp())) + { + cloneDecoration(nullptr, decoration, val, var->getModule()); + } + break; + case kIROp_NameHintDecoration: + // If the target already contains a linkage decoration, don't add + // a name decoration to avoid issues with emit logic. + if (!val->findDecorationImpl(decoration->getOp()) && !val->findDecoration()) { cloneDecoration(nullptr, decoration, val, var->getModule()); } diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp index f642409a1..b1a38febd 100644 --- a/source/slang/slang-lower-to-ir.cpp +++ b/source/slang/slang-lower-to-ir.cpp @@ -98,6 +98,7 @@ struct SwizzledLValueInfo; struct SwizzledMatrixLValueInfo; struct CopiedValInfo; struct ExtractedExistentialValInfo; +struct ImplicitCastLValueInfo; // This type is our core representation of lowered values. // In the simple case, it just wraps an `IRInst*`. @@ -138,6 +139,9 @@ struct LoweredValInfo // The value extracted from an opened existential ExtractedExistential, + + // The L-Value that is an implicit cast. + ImplicitCastedLValue, }; union @@ -217,6 +221,9 @@ struct LoweredValInfo static LoweredValInfo swizzledMatrixLValue( SwizzledMatrixLValueInfo* extInfo); + static LoweredValInfo implicitCastedLValue( + ImplicitCastLValueInfo* extInfo); + SwizzledLValueInfo* getSwizzledLValueInfo() { SLANG_ASSERT(flavor == Flavor::SwizzledLValue); @@ -237,6 +244,12 @@ struct LoweredValInfo SLANG_ASSERT(flavor == Flavor::ExtractedExistential); return (ExtractedExistentialValInfo*)ext; } + + ImplicitCastLValueInfo* getImplicitCastedLValue() + { + SLANG_ASSERT(flavor == Flavor::ImplicitCastedLValue); + return (ImplicitCastLValueInfo*)ext; + } }; // This case is used to indicate a reference to an AST-level @@ -362,6 +375,18 @@ struct ExtractedExistentialValInfo : ExtendedValueInfo IRInst* witnessTable; }; +struct ImplicitCastLValueInfo : ExtendedValueInfo +{ + // The type of the expression. + IRType* type; + + // The base expression (this should be an l-value) + LoweredValInfo base; + + // The type of the lvalue (inout, out, ref, etc.) + ParameterDirection lValueType; +}; + LoweredValInfo LoweredValInfo::boundMember( BoundMemberInfo* boundMemberInfo) { @@ -407,6 +432,15 @@ LoweredValInfo LoweredValInfo::swizzledMatrixLValue( return info; } +LoweredValInfo LoweredValInfo::implicitCastedLValue( + ImplicitCastLValueInfo* extInfo) +{ + LoweredValInfo info; + info.flavor = Flavor::ImplicitCastedLValue; + info.ext = extInfo; + return info; +} + LoweredValInfo LoweredValInfo::extractedExistential( ExtractedExistentialValInfo* extInfo) { @@ -1124,7 +1158,13 @@ top: return LoweredValInfo::simple(info->extractedVal); } - + case LoweredValInfo::Flavor::ImplicitCastedLValue: + { + auto info = lowered.getImplicitCastedLValue(); + auto baseVal = materialize(context, info->base); + auto result = builder->emitCast(info->type, getSimpleVal(context, baseVal)); + return LoweredValInfo::simple(result); + } default: SLANG_UNEXPECTED("unhandled value flavor"); UNREACHABLE_RETURN(LoweredValInfo()); @@ -4461,30 +4501,17 @@ struct LValueExprLoweringVisitor : ExprLoweringVisitorBasetype); - auto irPtrType = builder->getPtrType(irType); - auto loweredArg = lowerLValueExpr(context, expr->arguments[0]); - // It should be a ptr, because it is a LValue - SLANG_ASSERT(loweredArg.flavor == LoweredValInfo::Flavor::Ptr); - - // We have the irValue (which should be a Ptr because it's an LValue) - auto irLValue = loweredArg.val; - - IRInst* irCast = nullptr; + RefPtr lValueInfo = new ImplicitCastLValueInfo(); + lValueInfo->type = irType; + lValueInfo->base = loweredArg; + lValueInfo->lValueType = kParameterDirection_InOut; if (as(expr)) - { - irCast = builder->emitOutImplicitCast(irPtrType, irLValue); - } - else - { - irCast = builder->emitInOutImplicitCast(irPtrType, irLValue); - } - - return LoweredValInfo::ptr(irCast); + lValueInfo->lValueType = kParameterDirection_Out; + context->shared->extValues.add(lValueInfo); + return LoweredValInfo::implicitCastedLValue(lValueInfo); } // When visiting a swizzle expression in an l-value context, @@ -5850,7 +5877,21 @@ LoweredValInfo tryGetAddress( return LoweredValInfo::swizzledMatrixLValue(newSwizzleInfo); } break; - + case LoweredValInfo::Flavor::ImplicitCastedLValue: + { + auto info = val.getImplicitCastedLValue(); + auto baseAddr = tryGetAddress(context, info->base, TryGetAddressMode::Aggressive); + if (baseAddr.flavor == LoweredValInfo::Flavor::Ptr) + { + IRInst* result = nullptr; + if (info->lValueType == kParameterDirection_InOut) + result = context->irBuilder->emitInOutImplicitCast(context->irBuilder->getPtrType(info->type), baseAddr.val); + else + result = context->irBuilder->emitOutImplicitCast(context->irBuilder->getPtrType(info->type), baseAddr.val); + return LoweredValInfo::ptr(result); + } + } + break; // TODO: are there other cases we need to handled here? default: @@ -6242,6 +6283,16 @@ top: } break; + case LoweredValInfo::Flavor::ImplicitCastedLValue: + { + auto leftInfo = left.getImplicitCastedLValue(); + left = leftInfo->base; + auto rightVal = getSimpleVal(context, right); + right = LoweredValInfo::simple(builder->emitCast(leftInfo->type, rightVal)); + goto top; + } + break; + default: SLANG_UNIMPLEMENTED_X("assignment"); break; diff --git a/tests/bugs/gh-3075.slang b/tests/bugs/gh-3075.slang new file mode 100644 index 000000000..098d5b9ac --- /dev/null +++ b/tests/bugs/gh-3075.slang @@ -0,0 +1,15 @@ +//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -dx12 -profile sm_6_0 -use-dxil -output-using-type +//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -dx11 -profile sm_5_0 -output-using-type + +//TEST(compute, vulkan):COMPARE_COMPUTE_EX:-vk -compute -output-using-type +//TEST_INPUT:ubuffer(data=[0], stride=4):out,name=outputBuffer + +RWStructuredBuffer outputBuffer; + +[numthreads(1, 1, 1)] +void computeMain(uint3 dispatchThreadID: SV_DispatchThreadID) +{ + uint3 vLookup = 3; + vLookup.yx += int2(1, 2); // calling += (inout int2, int2). + outputBuffer[dispatchThreadID.x] = vLookup.x; // expect 5 +} diff --git a/tests/bugs/gh-3075.slang.expected.txt b/tests/bugs/gh-3075.slang.expected.txt new file mode 100644 index 000000000..65942e5f5 --- /dev/null +++ b/tests/bugs/gh-3075.slang.expected.txt @@ -0,0 +1,2 @@ +type: int32_t +5 \ No newline at end of file diff --git a/tests/bugs/implicit-cast.slang b/tests/bugs/implicit-cast.slang new file mode 100644 index 000000000..2ee62cc87 --- /dev/null +++ b/tests/bugs/implicit-cast.slang @@ -0,0 +1,18 @@ +//TEST(compute):COMPARE_COMPUTE:-vk -shaderobj + +//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name gBuffer +RWStructuredBuffer gBuffer; + +int getX(int4 v) { return v.x; } + +[numthreads(1, 1, 1)] +void computeMain(uint3 tid: SV_DispatchThreadID, uint GI: SV_GroupIndex) +{ + if (GI< 1) + { + uint LdsCoord = GI; + uint a = gBuffer[LdsCoord]; + LdsCoord += 1; + gBuffer[LdsCoord] = 1; + } +} diff --git a/tests/bugs/implicit-cast.slang.expected.txt b/tests/bugs/implicit-cast.slang.expected.txt new file mode 100644 index 000000000..d8263ee98 --- /dev/null +++ b/tests/bugs/implicit-cast.slang.expected.txt @@ -0,0 +1 @@ +2 \ No newline at end of file diff --git a/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-make-hit.slang.1.expected b/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-make-hit.slang.1.expected index c9589b805..0fd0214e4 100644 --- a/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-make-hit.slang.1.expected +++ b/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-make-hit.slang.1.expected @@ -62,7 +62,7 @@ uint calcValue_0(hitObjectNV hit_0) RayDesc_0 ray_1 = HitObject_GetRayDesc_0(hit_0); uint r_2 = r_1 + uint(ray_1.TMin_0 > 0.0) + uint(ray_1.TMax_0 < ray_1.TMin_0); SomeValues_0 objSomeValues_0 = HitObject_GetAttributes_0(hit_0); - r_0 = r_2 + uint(objSomeValues_0.a_0); + r_0 = uint(int(r_2) + objSomeValues_0.a_0); } else { diff --git a/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-reorder-thread.slang.1.expected b/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-reorder-thread.slang.1.expected index 09c410591..ae8efee2b 100644 --- a/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-reorder-thread.slang.1.expected +++ b/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-reorder-thread.slang.1.expected @@ -48,7 +48,7 @@ uint calcValue_0(hitObjectNV hit_0) uint geometryIndex_0 = (hitObjectGetGeometryIndexNV((hit_0))); uint primitiveIndex_0 = (hitObjectGetPrimitiveIndexNV((hit_0))); SomeValues_0 objSomeValues_0 = HitObject_GetAttributes_0(hit_0); - r_0 = instanceIndex_0 + instanceID_0 + geometryIndex_0 + primitiveIndex_0 + uint(objSomeValues_0.a_0); + r_0 = uint(int(instanceIndex_0 + instanceID_0 + geometryIndex_0 + primitiveIndex_0) + objSomeValues_0.a_0); } else { diff --git a/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-reorder-thread.slang.expected b/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-reorder-thread.slang.expected index 3ceaf339d..ae8efee2b 100644 --- a/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-reorder-thread.slang.expected +++ b/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-reorder-thread.slang.expected @@ -2,515 +2,120 @@ result code = 0 standard error = { } standard output = { -; -; Note: shader requires additional functionality: -; UAVs at every shader stage -; -; shader hash: bddffb5dfe46c4eeab7a59533e8200ba -; -; Buffer Definitions: -; -; Resource bind info for g_NvidiaExt -; { -; -; struct struct.NvShaderExtnStruct -; { -; -; uint opcode; ; Offset: 0 -; uint rid; ; Offset: 4 -; uint sid; ; Offset: 8 -; uint4 dst1u; ; Offset: 12 -; uint4 src3u; ; Offset: 28 -; uint4 src4u; ; Offset: 44 -; uint4 src5u; ; Offset: 60 -; uint4 src0u; ; Offset: 76 -; uint4 src1u; ; Offset: 92 -; uint4 src2u; ; Offset: 108 -; uint4 dst0u; ; Offset: 124 -; uint markUavRef; ; Offset: 140 -; uint numOutputsForIncCounter; ; Offset: 144 -; float padding1[27]; ; Offset: 148 -; -; } $Element; ; Offset: 0 Size: 256 -; -; } -; -; Resource bind info for outputBuffer_0 -; { -; -; uint $Element; ; Offset: 0 Size: 4 -; -; } -; -; -; Resource Bindings: -; -; Name Type Format Dim ID HLSL Bind Count -; ------------------------------ ---------- ------- ----------- ------- -------------- ------ -; scene_0 texture i32 ras T0 t0 1 -; g_NvidiaExt UAV struct r/w+cnt U0 u0 1 -; outputBuffer_0 UAV struct r/w U1 u1 1 -; -target datalayout = "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:32-f64:64-n8:16:32:64" -target triple = "dxil-ms-dx" - -%"class.RWStructuredBuffer" = type { %struct.NvShaderExtnStruct } -%struct.NvShaderExtnStruct = type { i32, i32, i32, <4 x i32>, <4 x i32>, <4 x i32>, <4 x i32>, <4 x i32>, <4 x i32>, <4 x i32>, <4 x i32>, i32, i32, [27 x float] } -%struct.RaytracingAccelerationStructure = type { i32 } -%"class.RWStructuredBuffer" = type { i32 } -%struct.SomeValues_0 = type { i32, float } -%dx.types.Handle = type { i8* } - -@"\01?g_NvidiaExt@@3V?$RWStructuredBuffer@UNvShaderExtnStruct@@@@A" = external constant %"class.RWStructuredBuffer", align 4 -@"\01?scene_0@@3URaytracingAccelerationStructure@@A" = external constant %struct.RaytracingAccelerationStructure, align 4 -@"\01?outputBuffer_0@@3V?$RWStructuredBuffer@I@@A" = external constant %"class.RWStructuredBuffer", align 4 - -; Function Attrs: nounwind -define void @"\01?rayGenerationMain@@YAXXZ"() #0 { - %1 = load %struct.RaytracingAccelerationStructure, %struct.RaytracingAccelerationStructure* @"\01?scene_0@@3URaytracingAccelerationStructure@@A", align 4, !noalias !18 - %2 = load %"class.RWStructuredBuffer", %"class.RWStructuredBuffer"* @"\01?outputBuffer_0@@3V?$RWStructuredBuffer@I@@A", align 4 - %3 = load %"class.RWStructuredBuffer", %"class.RWStructuredBuffer"* @"\01?g_NvidiaExt@@3V?$RWStructuredBuffer@UNvShaderExtnStruct@@@@A", align 4, !noalias !22 - %4 = alloca %struct.SomeValues_0, align 8 - %5 = alloca %struct.SomeValues_0, align 8 - %6 = alloca %struct.SomeValues_0, align 8 - %7 = alloca %struct.SomeValues_0, align 8 - %8 = alloca %struct.SomeValues_0, align 4 - %9 = alloca %struct.SomeValues_0, align 4 - %10 = call i32 @dx.op.dispatchRaysIndex.i32(i32 145, i8 0) ; DispatchRaysIndex(col) - %11 = sitofp i32 %10 to float - %12 = fmul fast float %11, 2.000000e+00 - %13 = getelementptr inbounds %struct.SomeValues_0, %struct.SomeValues_0* %8, i32 0, i32 0 - store i32 %10, i32* %13, align 4 - %14 = getelementptr inbounds %struct.SomeValues_0, %struct.SomeValues_0* %8, i32 0, i32 1 - store float %12, float* %14, align 4 - %15 = sitofp i32 %10 to float - %16 = call %dx.types.Handle @"dx.op.createHandleForLib.class.RWStructuredBuffer"(i32 160, %"class.RWStructuredBuffer" %3) ; CreateHandleForLib(Resource) - %17 = call i32 @dx.op.bufferUpdateCounter(i32 70, %dx.types.Handle %16, i8 1) ; BufferUpdateCounter(uav,inc) - %18 = call %dx.types.Handle @"dx.op.createHandleForLib.class.RWStructuredBuffer"(i32 160, %"class.RWStructuredBuffer" %3) ; CreateHandleForLib(Resource) - call void @dx.op.rawBufferStore.i32(i32 140, %dx.types.Handle %18, i32 %17, i32 0, i32 67, i32 undef, i32 undef, i32 undef, i8 1, i32 4) ; RawBufferStore(uav,index,elementOffset,value0,value1,value2,value3,mask,alignment) - %19 = call %dx.types.Handle @"dx.op.createHandleForLib.class.RWStructuredBuffer"(i32 160, %"class.RWStructuredBuffer" %3) ; CreateHandleForLib(Resource) - call void @dx.op.rawBufferStore.i32(i32 140, %dx.types.Handle %19, i32 %17, i32 144, i32 2, i32 undef, i32 undef, i32 undef, i8 1, i32 4) ; RawBufferStore(uav,index,elementOffset,value0,value1,value2,value3,mask,alignment) - %20 = call %dx.types.Handle @"dx.op.createHandleForLib.class.RWStructuredBuffer"(i32 160, %"class.RWStructuredBuffer" %3) ; CreateHandleForLib(Resource) - call void @dx.op.rawBufferStore.i32(i32 140, %dx.types.Handle %20, i32 %17, i32 76, i32 0, i32 undef, i32 undef, i32 undef, i8 1, i32 4) ; RawBufferStore(uav,index,elementOffset,value0,value1,value2,value3,mask,alignment) - %21 = call %dx.types.Handle @"dx.op.createHandleForLib.class.RWStructuredBuffer"(i32 160, %"class.RWStructuredBuffer" %3) ; CreateHandleForLib(Resource) - %22 = call i32 @dx.op.bufferUpdateCounter(i32 70, %dx.types.Handle %21, i8 1) ; BufferUpdateCounter(uav,inc) - %23 = call %dx.types.Handle @"dx.op.createHandleForLib.class.RWStructuredBuffer"(i32 160, %"class.RWStructuredBuffer" %3) ; CreateHandleForLib(Resource) - %24 = call i32 @dx.op.bufferUpdateCounter(i32 70, %dx.types.Handle %23, i8 1) ; BufferUpdateCounter(uav,inc) - %25 = call %dx.types.Handle @dx.op.createHandleForLib.struct.RaytracingAccelerationStructure(i32 160, %struct.RaytracingAccelerationStructure %1) ; CreateHandleForLib(Resource) - call void @dx.op.traceRay.struct.SomeValues_0(i32 157, %dx.types.Handle %25, i32 20, i32 255, i32 0, i32 4, i32 %24, float %15, float 0.000000e+00, float 0.000000e+00, float 0x3F847AE140000000, float 0.000000e+00, float 1.000000e+00, float 0.000000e+00, float 1.000000e+04, %struct.SomeValues_0* nonnull %8) ; TraceRay(AccelerationStructure,RayFlags,InstanceInclusionMask,RayContributionToHitGroupIndex,MultiplierForGeometryContributionToShaderIndex,MissShaderIndex,Origin_X,Origin_Y,Origin_Z,TMin,Direction_X,Direction_Y,Direction_Z,TMax,payload) - %26 = call %dx.types.Handle @"dx.op.createHandleForLib.class.RWStructuredBuffer"(i32 160, %"class.RWStructuredBuffer" %3) ; CreateHandleForLib(Resource) - %27 = call i32 @dx.op.bufferUpdateCounter(i32 70, %dx.types.Handle %26, i8 1) ; BufferUpdateCounter(uav,inc) - %28 = call %dx.types.Handle @"dx.op.createHandleForLib.class.RWStructuredBuffer"(i32 160, %"class.RWStructuredBuffer" %3) ; CreateHandleForLib(Resource) - call void @dx.op.rawBufferStore.i32(i32 140, %dx.types.Handle %28, i32 %27, i32 0, i32 83, i32 undef, i32 undef, i32 undef, i8 1, i32 4) ; RawBufferStore(uav,index,elementOffset,value0,value1,value2,value3,mask,alignment) - %29 = call %dx.types.Handle @"dx.op.createHandleForLib.class.RWStructuredBuffer"(i32 160, %"class.RWStructuredBuffer" %3) ; CreateHandleForLib(Resource) - call void @dx.op.rawBufferStore.i32(i32 140, %dx.types.Handle %29, i32 %27, i32 76, i32 %22, i32 undef, i32 undef, i32 undef, i8 1, i32 4) ; RawBufferStore(uav,index,elementOffset,value0,value1,value2,value3,mask,alignment) - %30 = call %dx.types.Handle @"dx.op.createHandleForLib.class.RWStructuredBuffer"(i32 160, %"class.RWStructuredBuffer" %3) ; CreateHandleForLib(Resource) - %31 = call i32 @dx.op.bufferUpdateCounter(i32 70, %dx.types.Handle %30, i8 1) ; BufferUpdateCounter(uav,inc) - %32 = icmp eq i32 %31, 0 - br i1 %32, label %70, label %33 - -;