|
@@ -0,0 +1,419 @@
|
|
|
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
|
+From: Antonio Maiorano <[email protected]>
|
|
|
+Date: Wed, 8 May 2024 13:38:38 -0400
|
|
|
+Subject: Fix invalid IR from scalarrepl-param-hlsl in ReplaceConstantWithInst
|
|
|
+ (#6556)
|
|
|
+
|
|
|
+ReplaceConstantWithInst(C, V) replaces uses of C in the current function
|
|
|
+with V. If such a use C is an instruction I, the it replaces uses of C
|
|
|
+in I with V. However, this function did not make sure to only perform
|
|
|
+this replacement if V dominates I. As a result, it may end up replacing
|
|
|
+uses of C in instructions before the definition of V.
|
|
|
+
|
|
|
+The fix is to lazily compute the dominator tree in
|
|
|
+ReplaceConstantWithInst so that we can guard the replacement with that
|
|
|
+dominance check.
|
|
|
+
|
|
|
+Bug: chromium:333414294
|
|
|
+Change-Id: I2a8bf64094298b49a1887cc7c1334e91a745c396
|
|
|
+Reviewed-on: https://chromium-review.googlesource.com/c/external/github.com/microsoft/DirectXShaderCompiler/+/5525429
|
|
|
+Reviewed-by: James Price <[email protected]>
|
|
|
+Reviewed-by: dan sinclair <[email protected]>
|
|
|
+
|
|
|
+diff --git a/lib/Transforms/Scalar/ScalarReplAggregatesHLSL.cpp b/lib/Transforms/Scalar/ScalarReplAggregatesHLSL.cpp
|
|
|
+index 3f8ffdbcfa09a96899295fd85291cedb879a248b..9b843ef0e49e554001b827e30eb6256853d90f5b 100644
|
|
|
+--- a/lib/Transforms/Scalar/ScalarReplAggregatesHLSL.cpp
|
|
|
++++ b/lib/Transforms/Scalar/ScalarReplAggregatesHLSL.cpp
|
|
|
+@@ -3271,15 +3271,34 @@ bool SROA_Helper::DoScalarReplacement(GlobalVariable *GV,
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+-static void ReplaceConstantWithInst(Constant *C, Value *V,
|
|
|
++// Replaces uses of constant C in the current function
|
|
|
++// with V, when those uses are dominated by V.
|
|
|
++// Returns true if it was completely replaced.
|
|
|
++static bool ReplaceConstantWithInst(Constant *C, Value *V,
|
|
|
+ IRBuilder<> &Builder) {
|
|
|
++ bool bReplacedAll = true;
|
|
|
+ Function *F = Builder.GetInsertBlock()->getParent();
|
|
|
++ Instruction *VInst = dyn_cast<Instruction>(V);
|
|
|
++ // Lazily calculate dominance
|
|
|
++ DominatorTree DT;
|
|
|
++ bool Calculated = false;
|
|
|
++ auto Dominates = [&](llvm::Instruction *Def, llvm::Instruction *User) {
|
|
|
++ if (!Calculated) {
|
|
|
++ DT.recalculate(*F);
|
|
|
++ Calculated = true;
|
|
|
++ }
|
|
|
++ return DT.dominates(Def, User);
|
|
|
++ };
|
|
|
++
|
|
|
+ for (auto it = C->user_begin(); it != C->user_end();) {
|
|
|
+ User *U = *(it++);
|
|
|
+ if (Instruction *I = dyn_cast<Instruction>(U)) {
|
|
|
+ if (I->getParent()->getParent() != F)
|
|
|
+ continue;
|
|
|
+- I->replaceUsesOfWith(C, V);
|
|
|
++ if (VInst && Dominates(VInst, I))
|
|
|
++ I->replaceUsesOfWith(C, V);
|
|
|
++ else
|
|
|
++ bReplacedAll = false;
|
|
|
+ } else {
|
|
|
+ // Skip unused ConstantExpr.
|
|
|
+ if (U->user_empty())
|
|
|
+@@ -3288,10 +3307,12 @@ static void ReplaceConstantWithInst(Constant *C, Value *V,
|
|
|
+ Instruction *Inst = CE->getAsInstruction();
|
|
|
+ Builder.Insert(Inst);
|
|
|
+ Inst->replaceUsesOfWith(C, V);
|
|
|
+- ReplaceConstantWithInst(CE, Inst, Builder);
|
|
|
++ if (!ReplaceConstantWithInst(CE, Inst, Builder))
|
|
|
++ bReplacedAll = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ C->removeDeadConstantUsers();
|
|
|
++ return bReplacedAll;
|
|
|
+ }
|
|
|
+
|
|
|
+ static void ReplaceUnboundedArrayUses(Value *V, Value *Src) {
|
|
|
+@@ -3531,7 +3552,8 @@ static bool ReplaceMemcpy(Value *V, Value *Src, MemCpyInst *MC,
|
|
|
+ } else {
|
|
|
+ // Replace Constant with a non-Constant.
|
|
|
+ IRBuilder<> Builder(MC);
|
|
|
+- ReplaceConstantWithInst(C, Src, Builder);
|
|
|
++ if (!ReplaceConstantWithInst(C, Src, Builder))
|
|
|
++ return false;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // Try convert special pattern for cbuffer which copy array of float4 to
|
|
|
+@@ -3539,7 +3561,8 @@ static bool ReplaceMemcpy(Value *V, Value *Src, MemCpyInst *MC,
|
|
|
+ if (!tryToReplaceCBVec4ArrayToScalarArray(V, TyV, Src, TySrc, MC, DL)) {
|
|
|
+ IRBuilder<> Builder(MC);
|
|
|
+ Src = Builder.CreateBitCast(Src, V->getType());
|
|
|
+- ReplaceConstantWithInst(C, Src, Builder);
|
|
|
++ if (!ReplaceConstantWithInst(C, Src, Builder))
|
|
|
++ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+@@ -5447,9 +5470,9 @@ void SROA_Parameter_HLSL::flattenArgument(
|
|
|
+ if (Ty->isPointerTy())
|
|
|
+ Ty = Ty->getPointerElementType();
|
|
|
+ unsigned size = DL.getTypeAllocSize(Ty);
|
|
|
+-#if 0 // HLSL Change
|
|
|
++#if 0 // HLSL Change
|
|
|
+ DIExpression *DDIExp = DIB.createBitPieceExpression(debugOffset, size);
|
|
|
+-#else // HLSL Change
|
|
|
++#else // HLSL Change
|
|
|
+ Type *argTy = Arg->getType();
|
|
|
+ if (argTy->isPointerTy())
|
|
|
+ argTy = argTy->getPointerElementType();
|
|
|
+diff --git a/tools/clang/test/DXC/Passes/ScalarReplHLSL/scalarrepl-param-hlsl-const-to-local-and-back.hlsl b/tools/clang/test/DXC/Passes/ScalarReplHLSL/scalarrepl-param-hlsl-const-to-local-and-back.hlsl
|
|
|
+new file mode 100644
|
|
|
+index 0000000000000000000000000000000000000000..0f30050e69decaf7da3f2ae645611c1a49a4a719
|
|
|
+--- /dev/null
|
|
|
++++ b/tools/clang/test/DXC/Passes/ScalarReplHLSL/scalarrepl-param-hlsl-const-to-local-and-back.hlsl
|
|
|
+@@ -0,0 +1,45 @@
|
|
|
++// RUN: not %dxc -T ps_6_2 %s 2>&1 | FileCheck %s
|
|
|
++
|
|
|
++// Validate that copying from static array to local, then back to static
|
|
|
++// array does not crash the compiler. This was resulting in an invalid
|
|
|
++// ReplaceConstantWithInst from ScalarReplAggregatesHLSL, which would
|
|
|
++// result in referenced deleted instruction in a later pass.
|
|
|
++
|
|
|
++// CHECK: error: Loop must have break.
|
|
|
++
|
|
|
++static int arr1[10] = (int[10])0;
|
|
|
++static int arr2[10] = (int[10])0;
|
|
|
++static float result = 0;
|
|
|
++ByteAddressBuffer buff : register(t0);
|
|
|
++
|
|
|
++void foo() {
|
|
|
++ int i = 0;
|
|
|
++ if (buff.Load(0u)) {
|
|
|
++ return;
|
|
|
++ }
|
|
|
++ arr2[i] = arr1[i];
|
|
|
++ result = float(arr1[0]);
|
|
|
++}
|
|
|
++
|
|
|
++struct tint_symbol {
|
|
|
++ float4 value : SV_Target0;
|
|
|
++};
|
|
|
++
|
|
|
++float main_inner() {
|
|
|
++ foo();
|
|
|
++ bool cond = false;
|
|
|
++ while (true) {
|
|
|
++ if (cond) { break; }
|
|
|
++ }
|
|
|
++ int arr1_copy[10] = arr1; // constant to local
|
|
|
++ arr1 = arr1_copy; // local to constant
|
|
|
++ foo();
|
|
|
++ return result;
|
|
|
++}
|
|
|
++
|
|
|
++tint_symbol main() {
|
|
|
++ float inner_result = main_inner();
|
|
|
++ tint_symbol wrapper_result = (tint_symbol)0;
|
|
|
++ wrapper_result.value.x = inner_result;
|
|
|
++ return wrapper_result;
|
|
|
++}
|
|
|
+diff --git a/tools/clang/test/DXC/Passes/ScalarReplHLSL/scalarrepl-param-hlsl-const-to-local-and-back.ll b/tools/clang/test/DXC/Passes/ScalarReplHLSL/scalarrepl-param-hlsl-const-to-local-and-back.ll
|
|
|
+new file mode 100644
|
|
|
+index 0000000000000000000000000000000000000000..6ca08ab3a9c500cacb715f63ee407c7add4fc51c
|
|
|
+--- /dev/null
|
|
|
++++ b/tools/clang/test/DXC/Passes/ScalarReplHLSL/scalarrepl-param-hlsl-const-to-local-and-back.ll
|
|
|
+@@ -0,0 +1,253 @@
|
|
|
++; RUN: %dxopt %s -hlsl-passes-resume -scalarrepl-param-hlsl -S | FileCheck %s
|
|
|
++
|
|
|
++; The first memcpy, from arr1 to arr1_copy.i, should be replaced by a series of 10 loads and stores,
|
|
|
++; while the second memcpy, from arr1_copy.i back to arr1, should be removed:
|
|
|
++; %19 = bitcast [10 x i32]* %arr1_copy.i to i8*, !dbg !33 ; line:25 col:23
|
|
|
++; call void @llvm.memcpy.p0i8.p0i8.i64(i8* %19, i8* bitcast ([10 x i32]* @arr1 to i8*), i64 40, i32 1, i1 false) #0, !dbg !33 ; line:25 col:23
|
|
|
++; %20 = bitcast [10 x i32]* %arr1_copy.i to i8*, !dbg !34 ; line:26 col:10
|
|
|
++; call void @llvm.memcpy.p0i8.p0i8.i64(i8* bitcast ([10 x i32]* @arr1 to i8*), i8* %20, i64 40, i32 1, i1 false) #0, !dbg !34 ; line:26 col:10
|
|
|
++; store i32 0, i32* %i.i.1.i, align 4, !dbg !35, !tbaa !12 ; line:7 col:7
|
|
|
++
|
|
|
++; CHECK: [[DEST0:%[a-z0-9\.]+]] = getelementptr inbounds [10 x i32], [10 x i32]* %arr1_copy.i, i32 0, i32 0
|
|
|
++; CHECK-NEXT: [[SRC0:%[a-z0-9\.]+]] = load i32, i32* getelementptr inbounds ([10 x i32], [10 x i32]* @arr1, i32 0, i32 0)
|
|
|
++; CHECK-NEXT: store i32 [[SRC0:%[a-z0-9\.]+]], i32* [[DEST0:%[a-z0-9\.]+]]
|
|
|
++; CHECK-NEXT: [[DEST1:%[a-z0-9\.]+]] = getelementptr inbounds [10 x i32], [10 x i32]* %arr1_copy.i, i32 0, i32 1
|
|
|
++; CHECK-NEXT: [[SRC1:%[a-z0-9\.]+]] = load i32, i32* getelementptr inbounds ([10 x i32], [10 x i32]* @arr1, i32 0, i32 1)
|
|
|
++; CHECK-NEXT: store i32 [[SRC1:%[a-z0-9\.]+]], i32* [[DEST1:%[a-z0-9\.]+]]
|
|
|
++; CHECK-NEXT: [[DEST2:%[a-z0-9\.]+]] = getelementptr inbounds [10 x i32], [10 x i32]* %arr1_copy.i, i32 0, i32 2
|
|
|
++; CHECK-NEXT: [[SRC2:%[a-z0-9\.]+]] = load i32, i32* getelementptr inbounds ([10 x i32], [10 x i32]* @arr1, i32 0, i32 2)
|
|
|
++; CHECK-NEXT: store i32 [[SRC2:%[a-z0-9\.]+]], i32* [[DEST2:%[a-z0-9\.]+]]
|
|
|
++; CHECK-NEXT: [[DEST3:%[a-z0-9\.]+]] = getelementptr inbounds [10 x i32], [10 x i32]* %arr1_copy.i, i32 0, i32 3
|
|
|
++; CHECK-NEXT: [[SRC3:%[a-z0-9\.]+]] = load i32, i32* getelementptr inbounds ([10 x i32], [10 x i32]* @arr1, i32 0, i32 3)
|
|
|
++; CHECK-NEXT: store i32 [[SRC3:%[a-z0-9\.]+]], i32* [[DEST3:%[a-z0-9\.]+]]
|
|
|
++; CHECK-NEXT: [[DEST4:%[a-z0-9\.]+]] = getelementptr inbounds [10 x i32], [10 x i32]* %arr1_copy.i, i32 0, i32 4
|
|
|
++; CHECK-NEXT: [[SRC4:%[a-z0-9\.]+]] = load i32, i32* getelementptr inbounds ([10 x i32], [10 x i32]* @arr1, i32 0, i32 4)
|
|
|
++; CHECK-NEXT: store i32 [[SRC4:%[a-z0-9\.]+]], i32* [[DEST4:%[a-z0-9\.]+]]
|
|
|
++; CHECK-NEXT: [[DEST5:%[a-z0-9\.]+]] = getelementptr inbounds [10 x i32], [10 x i32]* %arr1_copy.i, i32 0, i32 5
|
|
|
++; CHECK-NEXT: [[SRC5:%[a-z0-9\.]+]] = load i32, i32* getelementptr inbounds ([10 x i32], [10 x i32]* @arr1, i32 0, i32 5)
|
|
|
++; CHECK-NEXT: store i32 [[SRC5:%[a-z0-9\.]+]], i32* [[DEST5:%[a-z0-9\.]+]]
|
|
|
++; CHECK-NEXT: [[DEST6:%[a-z0-9\.]+]] = getelementptr inbounds [10 x i32], [10 x i32]* %arr1_copy.i, i32 0, i32 6
|
|
|
++; CHECK-NEXT: [[SRC6:%[a-z0-9\.]+]] = load i32, i32* getelementptr inbounds ([10 x i32], [10 x i32]* @arr1, i32 0, i32 6)
|
|
|
++; CHECK-NEXT: store i32 [[SRC6:%[a-z0-9\.]+]], i32* [[DEST6:%[a-z0-9\.]+]]
|
|
|
++; CHECK-NEXT: [[DEST7:%[a-z0-9\.]+]] = getelementptr inbounds [10 x i32], [10 x i32]* %arr1_copy.i, i32 0, i32 7
|
|
|
++; CHECK-NEXT: [[SRC7:%[a-z0-9\.]+]] = load i32, i32* getelementptr inbounds ([10 x i32], [10 x i32]* @arr1, i32 0, i32 7)
|
|
|
++; CHECK-NEXT: store i32 [[SRC7:%[a-z0-9\.]+]], i32* [[DEST7:%[a-z0-9\.]+]]
|
|
|
++; CHECK-NEXT: [[DEST8:%[a-z0-9\.]+]] = getelementptr inbounds [10 x i32], [10 x i32]* %arr1_copy.i, i32 0, i32 8
|
|
|
++; CHECK-NEXT: [[SRC8:%[a-z0-9\.]+]] = load i32, i32* getelementptr inbounds ([10 x i32], [10 x i32]* @arr1, i32 0, i32 8)
|
|
|
++; CHECK-NEXT: store i32 [[SRC8:%[a-z0-9\.]+]], i32* [[DEST8:%[a-z0-9\.]+]]
|
|
|
++; CHECK-NEXT: [[DEST9:%[a-z0-9\.]+]] = getelementptr inbounds [10 x i32], [10 x i32]* %arr1_copy.i, i32 0, i32 9
|
|
|
++; CHECK-NEXT: [[SRC9:%[a-z0-9\.]+]] = load i32, i32* getelementptr inbounds ([10 x i32], [10 x i32]* @arr1, i32 0, i32 9)
|
|
|
++; CHECK-NEXT: store i32 [[SRC9:%[a-z0-9\.]+]], i32* [[DEST9:%[a-z0-9\.]+]]
|
|
|
++
|
|
|
++;
|
|
|
++; Buffer Definitions:
|
|
|
++;
|
|
|
++; cbuffer $Globals
|
|
|
++; {
|
|
|
++;
|
|
|
++; [0 x i8] (type annotation not present)
|
|
|
++;
|
|
|
++; }
|
|
|
++;
|
|
|
++;
|
|
|
++; Resource Bindings:
|
|
|
++;
|
|
|
++; Name Type Format Dim ID HLSL Bind Count
|
|
|
++; ------------------------------ ---------- ------- ----------- ------- -------------- ------
|
|
|
++; $Globals cbuffer NA NA CB0 cb4294967295 1
|
|
|
++; buff texture byte r/o T0 t0 1
|
|
|
++;
|
|
|
++target datalayout = "e-m:e-p:32:32-i1:32-i8:32-i16:32-i32:32-i64:64-f16:32-f32:32-f64:64-n8:16:32:64"
|
|
|
++target triple = "dxil-ms-dx"
|
|
|
++
|
|
|
++%struct.ByteAddressBuffer = type { i32 }
|
|
|
++%ConstantBuffer = type opaque
|
|
|
++%struct.tint_symbol = type { <4 x float> }
|
|
|
++%dx.types.Handle = type { i8* }
|
|
|
++%dx.types.ResourceProperties = type { i32, i32 }
|
|
|
++
|
|
|
++@"\01?buff@@3UByteAddressBuffer@@A" = external global %struct.ByteAddressBuffer, align 4
|
|
|
++@arr1 = internal global [10 x i32] zeroinitializer, align 4
|
|
|
++@arr2 = internal global [10 x i32] zeroinitializer, align 4
|
|
|
++@"$Globals" = external constant %ConstantBuffer
|
|
|
++
|
|
|
++; Function Attrs: nounwind
|
|
|
++define void @main(%struct.tint_symbol* noalias sret %agg.result) #0 {
|
|
|
++ %1 = alloca float
|
|
|
++ store float 0.000000e+00, float* %1
|
|
|
++ %i.i.1.i = alloca i32, align 4
|
|
|
++ %i.i.i = alloca i32, align 4
|
|
|
++ %cond.i = alloca i32, align 4
|
|
|
++ %arr1_copy.i = alloca [10 x i32], align 4
|
|
|
++ %inner_result = alloca float, align 4
|
|
|
++ %wrapper_result = alloca %struct.tint_symbol, align 4
|
|
|
++ store i32 0, i32* %i.i.i, align 4, !dbg !23, !tbaa !31 ; line:7 col:7
|
|
|
++ %2 = load %struct.ByteAddressBuffer, %struct.ByteAddressBuffer* @"\01?buff@@3UByteAddressBuffer@@A", !dbg !35 ; line:8 col:7
|
|
|
++ %3 = call %dx.types.Handle @"dx.hl.createhandle..%dx.types.Handle (i32, %struct.ByteAddressBuffer)"(i32 0, %struct.ByteAddressBuffer %2) #0, !dbg !35 ; line:8 col:7
|
|
|
++ %4 = call %dx.types.Handle @"dx.hl.annotatehandle..%dx.types.Handle (i32, %dx.types.Handle, %dx.types.ResourceProperties, %struct.ByteAddressBuffer)"(i32 14, %dx.types.Handle %3, %dx.types.ResourceProperties { i32 11, i32 0 }, %struct.ByteAddressBuffer undef) #0, !dbg !35 ; line:8 col:7
|
|
|
++ %5 = call i32 @"dx.hl.op.ro.i32 (i32, %dx.types.Handle, i32)"(i32 231, %dx.types.Handle %4, i32 0) #0, !dbg !35 ; line:8 col:7
|
|
|
++ %6 = icmp ne i32 %5, 0, !dbg !35 ; line:8 col:7
|
|
|
++ br i1 %6, label %"\01?foo@@YAXXZ.exit.i", label %7, !dbg !35 ; line:8 col:7
|
|
|
++
|
|
|
++; <label>:7 ; preds = %0
|
|
|
++ %8 = load i32, i32* %i.i.i, align 4, !dbg !36, !tbaa !31 ; line:11 col:18
|
|
|
++ %9 = getelementptr inbounds [10 x i32], [10 x i32]* @arr1, i32 0, i32 %8, !dbg !37 ; line:11 col:13
|
|
|
++ %10 = load i32, i32* %9, align 4, !dbg !37, !tbaa !31 ; line:11 col:13
|
|
|
++ %11 = load i32, i32* %i.i.i, align 4, !dbg !38, !tbaa !31 ; line:11 col:8
|
|
|
++ %12 = getelementptr inbounds [10 x i32], [10 x i32]* @arr2, i32 0, i32 %11, !dbg !39 ; line:11 col:3
|
|
|
++ store i32 %10, i32* %12, align 4, !dbg !40, !tbaa !31 ; line:11 col:11
|
|
|
++ %13 = load i32, i32* getelementptr inbounds ([10 x i32], [10 x i32]* @arr1, i32 0, i32 0), align 4, !dbg !41, !tbaa !31 ; line:12 col:18
|
|
|
++ %14 = sitofp i32 %13 to float, !dbg !41 ; line:12 col:18
|
|
|
++ store float %14, float* %1, align 4, !dbg !42, !tbaa !43 ; line:12 col:10
|
|
|
++ br label %"\01?foo@@YAXXZ.exit.i", !dbg !45 ; line:13 col:1
|
|
|
++
|
|
|
++"\01?foo@@YAXXZ.exit.i": ; preds = %7, %0
|
|
|
++ store i32 0, i32* %cond.i, align 4, !dbg !46, !tbaa !47 ; line:21 col:8
|
|
|
++ br label %15, !dbg !49 ; line:22 col:3
|
|
|
++
|
|
|
++; <label>:15 ; preds = %15, %"\01?foo@@YAXXZ.exit.i"
|
|
|
++ %16 = load i32, i32* %cond.i, align 4, !dbg !50, !tbaa !47, !range !51 ; line:23 col:9
|
|
|
++ %17 = icmp ne i32 %16, 0, !dbg !50 ; line:23 col:9
|
|
|
++ br i1 %17, label %18, label %15, !dbg !50 ; line:23 col:9
|
|
|
++
|
|
|
++; <label>:18 ; preds = %15
|
|
|
++ %19 = bitcast [10 x i32]* %arr1_copy.i to i8*, !dbg !52 ; line:25 col:23
|
|
|
++ call void @llvm.memcpy.p0i8.p0i8.i64(i8* %19, i8* bitcast ([10 x i32]* @arr1 to i8*), i64 40, i32 1, i1 false) #0, !dbg !52 ; line:25 col:23
|
|
|
++ %20 = bitcast [10 x i32]* %arr1_copy.i to i8*, !dbg !53 ; line:26 col:10
|
|
|
++ call void @llvm.memcpy.p0i8.p0i8.i64(i8* bitcast ([10 x i32]* @arr1 to i8*), i8* %20, i64 40, i32 1, i1 false) #0, !dbg !53 ; line:26 col:10
|
|
|
++ store i32 0, i32* %i.i.1.i, align 4, !dbg !54, !tbaa !31 ; line:7 col:7
|
|
|
++ %21 = load %struct.ByteAddressBuffer, %struct.ByteAddressBuffer* @"\01?buff@@3UByteAddressBuffer@@A", !dbg !56 ; line:8 col:7
|
|
|
++ %22 = call %dx.types.Handle @"dx.hl.createhandle..%dx.types.Handle (i32, %struct.ByteAddressBuffer)"(i32 0, %struct.ByteAddressBuffer %21) #0, !dbg !56 ; line:8 col:7
|
|
|
++ %23 = call %dx.types.Handle @"dx.hl.annotatehandle..%dx.types.Handle (i32, %dx.types.Handle, %dx.types.ResourceProperties, %struct.ByteAddressBuffer)"(i32 14, %dx.types.Handle %22, %dx.types.ResourceProperties { i32 11, i32 0 }, %struct.ByteAddressBuffer undef) #0, !dbg !56 ; line:8 col:7
|
|
|
++ %24 = call i32 @"dx.hl.op.ro.i32 (i32, %dx.types.Handle, i32)"(i32 231, %dx.types.Handle %23, i32 0) #0, !dbg !56 ; line:8 col:7
|
|
|
++ %25 = icmp ne i32 %24, 0, !dbg !56 ; line:8 col:7
|
|
|
++ br i1 %25, label %"\01?main_inner@@YAMXZ.exit", label %26, !dbg !56 ; line:8 col:7
|
|
|
++
|
|
|
++; <label>:26 ; preds = %18
|
|
|
++ %27 = load i32, i32* %i.i.1.i, align 4, !dbg !57, !tbaa !31 ; line:11 col:18
|
|
|
++ %28 = getelementptr inbounds [10 x i32], [10 x i32]* @arr1, i32 0, i32 %27, !dbg !58 ; line:11 col:13
|
|
|
++ %29 = load i32, i32* %28, align 4, !dbg !58, !tbaa !31 ; line:11 col:13
|
|
|
++ %30 = load i32, i32* %i.i.1.i, align 4, !dbg !59, !tbaa !31 ; line:11 col:8
|
|
|
++ %31 = getelementptr inbounds [10 x i32], [10 x i32]* @arr2, i32 0, i32 %30, !dbg !60 ; line:11 col:3
|
|
|
++ store i32 %29, i32* %31, align 4, !dbg !61, !tbaa !31 ; line:11 col:11
|
|
|
++ %32 = load i32, i32* getelementptr inbounds ([10 x i32], [10 x i32]* @arr1, i32 0, i32 0), align 4, !dbg !62, !tbaa !31 ; line:12 col:18
|
|
|
++ %33 = sitofp i32 %32 to float, !dbg !62 ; line:12 col:18
|
|
|
++ store float %33, float* %1, align 4, !dbg !63, !tbaa !43 ; line:12 col:10
|
|
|
++ br label %"\01?main_inner@@YAMXZ.exit", !dbg !64 ; line:13 col:1
|
|
|
++
|
|
|
++"\01?main_inner@@YAMXZ.exit": ; preds = %18, %26
|
|
|
++ %34 = load float, float* %1, align 4, !dbg !65, !tbaa !43 ; line:28 col:10
|
|
|
++ store float %34, float* %inner_result, align 4, !dbg !66, !tbaa !43 ; line:32 col:9
|
|
|
++ %35 = getelementptr inbounds %struct.tint_symbol, %struct.tint_symbol* %wrapper_result, i32 0, i32 0, !dbg !67 ; line:33 col:45
|
|
|
++ store <4 x float> zeroinitializer, <4 x float>* %35, !dbg !67 ; line:33 col:45
|
|
|
++ %36 = load float, float* %inner_result, align 4, !dbg !68, !tbaa !43 ; line:34 col:28
|
|
|
++ %37 = getelementptr inbounds %struct.tint_symbol, %struct.tint_symbol* %wrapper_result, i32 0, i32 0, !dbg !69 ; line:34 col:18
|
|
|
++ %38 = load <4 x float>, <4 x float>* %37, align 4, !dbg !70 ; line:34 col:26
|
|
|
++ %39 = getelementptr <4 x float>, <4 x float>* %37, i32 0, i32 0, !dbg !70 ; line:34 col:26
|
|
|
++ store float %36, float* %39, !dbg !70 ; line:34 col:26
|
|
|
++ %40 = bitcast %struct.tint_symbol* %agg.result to i8*, !dbg !71 ; line:35 col:10
|
|
|
++ %41 = bitcast %struct.tint_symbol* %wrapper_result to i8*, !dbg !71 ; line:35 col:10
|
|
|
++ call void @llvm.memcpy.p0i8.p0i8.i64(i8* %40, i8* %41, i64 16, i32 1, i1 false), !dbg !71 ; line:35 col:10
|
|
|
++ ret void, !dbg !72 ; line:35 col:3
|
|
|
++}
|
|
|
++
|
|
|
++; Function Attrs: nounwind
|
|
|
++declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i32, i1) #0
|
|
|
++
|
|
|
++; Function Attrs: nounwind readonly
|
|
|
++declare i32 @"dx.hl.op.ro.i32 (i32, %dx.types.Handle, i32)"(i32, %dx.types.Handle, i32) #1
|
|
|
++
|
|
|
++; Function Attrs: nounwind readnone
|
|
|
++declare %dx.types.Handle @"dx.hl.createhandle..%dx.types.Handle (i32, %struct.ByteAddressBuffer)"(i32, %struct.ByteAddressBuffer) #2
|
|
|
++
|
|
|
++; Function Attrs: nounwind readnone
|
|
|
++declare %dx.types.Handle @"dx.hl.annotatehandle..%dx.types.Handle (i32, %dx.types.Handle, %dx.types.ResourceProperties, %struct.ByteAddressBuffer)"(i32, %dx.types.Handle, %dx.types.ResourceProperties, %struct.ByteAddressBuffer) #2
|
|
|
++
|
|
|
++attributes #0 = { nounwind }
|
|
|
++attributes #1 = { nounwind readonly }
|
|
|
++attributes #2 = { nounwind readnone }
|
|
|
++
|
|
|
++!llvm.module.flags = !{!0}
|
|
|
++!pauseresume = !{!1}
|
|
|
++!llvm.ident = !{!2}
|
|
|
++!dx.version = !{!3}
|
|
|
++!dx.valver = !{!4}
|
|
|
++!dx.shaderModel = !{!5}
|
|
|
++!dx.typeAnnotations = !{!6, !9}
|
|
|
++!dx.entryPoints = !{!14}
|
|
|
++!dx.fnprops = !{!20}
|
|
|
++!dx.options = !{!21, !22}
|
|
|
++
|
|
|
++!0 = !{i32 2, !"Debug Info Version", i32 3}
|
|
|
++!1 = !{!"hlsl-hlemit", !"hlsl-hlensure"}
|
|
|
++!2 = !{!"dxc(private) 1.8.0.4547 (14ec4b49d)"}
|
|
|
++!3 = !{i32 1, i32 2}
|
|
|
++!4 = !{i32 1, i32 8}
|
|
|
++!5 = !{!"ps", i32 6, i32 2}
|
|
|
++!6 = !{i32 0, %struct.tint_symbol undef, !7}
|
|
|
++!7 = !{i32 16, !8}
|
|
|
++!8 = !{i32 6, !"value", i32 3, i32 0, i32 4, !"SV_Target0", i32 7, i32 9}
|
|
|
++!9 = !{i32 1, void (%struct.tint_symbol*)* @main, !10}
|
|
|
++!10 = !{!11, !13}
|
|
|
++!11 = !{i32 0, !12, !12}
|
|
|
++!12 = !{}
|
|
|
++!13 = !{i32 1, !12, !12}
|
|
|
++!14 = !{void (%struct.tint_symbol*)* @main, !"main", null, !15, null}
|
|
|
++!15 = !{!16, null, !18, null}
|
|
|
++!16 = !{!17}
|
|
|
++!17 = !{i32 0, %struct.ByteAddressBuffer* @"\01?buff@@3UByteAddressBuffer@@A", !"buff", i32 0, i32 0, i32 1, i32 11, i32 0, null}
|
|
|
++!18 = !{!19}
|
|
|
++!19 = !{i32 0, %ConstantBuffer* @"$Globals", !"$Globals", i32 0, i32 -1, i32 1, i32 0, null}
|
|
|
++!20 = !{void (%struct.tint_symbol*)* @main, i32 0, i1 false}
|
|
|
++!21 = !{i32 144}
|
|
|
++!22 = !{i32 -1}
|
|
|
++!23 = !DILocation(line: 7, column: 7, scope: !24, inlinedAt: !27)
|
|
|
++!24 = !DISubprogram(name: "foo", scope: !25, file: !25, line: 6, type: !26, isLocal: false, isDefinition: true, scopeLine: 6, flags: DIFlagPrototyped, isOptimized: false)
|
|
|
++!25 = !DIFile(filename: "333414294_simplifed.hlsl", directory: "")
|
|
|
++!26 = !DISubroutineType(types: !12)
|
|
|
++!27 = distinct !DILocation(line: 20, column: 3, scope: !28, inlinedAt: !29)
|
|
|
++!28 = !DISubprogram(name: "main_inner", scope: !25, file: !25, line: 19, type: !26, isLocal: false, isDefinition: true, scopeLine: 19, flags: DIFlagPrototyped, isOptimized: false)
|
|
|
++!29 = distinct !DILocation(line: 32, column: 24, scope: !30)
|
|
|
++!30 = !DISubprogram(name: "main", scope: !25, file: !25, line: 31, type: !26, isLocal: false, isDefinition: true, scopeLine: 31, flags: DIFlagPrototyped, isOptimized: false, function: void (%struct.tint_symbol*)* @main)
|
|
|
++!31 = !{!32, !32, i64 0}
|
|
|
++!32 = !{!"int", !33, i64 0}
|
|
|
++!33 = !{!"omnipotent char", !34, i64 0}
|
|
|
++!34 = !{!"Simple C/C++ TBAA"}
|
|
|
++!35 = !DILocation(line: 8, column: 7, scope: !24, inlinedAt: !27)
|
|
|
++!36 = !DILocation(line: 11, column: 18, scope: !24, inlinedAt: !27)
|
|
|
++!37 = !DILocation(line: 11, column: 13, scope: !24, inlinedAt: !27)
|
|
|
++!38 = !DILocation(line: 11, column: 8, scope: !24, inlinedAt: !27)
|
|
|
++!39 = !DILocation(line: 11, column: 3, scope: !24, inlinedAt: !27)
|
|
|
++!40 = !DILocation(line: 11, column: 11, scope: !24, inlinedAt: !27)
|
|
|
++!41 = !DILocation(line: 12, column: 18, scope: !24, inlinedAt: !27)
|
|
|
++!42 = !DILocation(line: 12, column: 10, scope: !24, inlinedAt: !27)
|
|
|
++!43 = !{!44, !44, i64 0}
|
|
|
++!44 = !{!"float", !33, i64 0}
|
|
|
++!45 = !DILocation(line: 13, column: 1, scope: !24, inlinedAt: !27)
|
|
|
++!46 = !DILocation(line: 21, column: 8, scope: !28, inlinedAt: !29)
|
|
|
++!47 = !{!48, !48, i64 0}
|
|
|
++!48 = !{!"bool", !33, i64 0}
|
|
|
++!49 = !DILocation(line: 22, column: 3, scope: !28, inlinedAt: !29)
|
|
|
++!50 = !DILocation(line: 23, column: 9, scope: !28, inlinedAt: !29)
|
|
|
++!51 = !{i32 0, i32 2}
|
|
|
++!52 = !DILocation(line: 25, column: 23, scope: !28, inlinedAt: !29)
|
|
|
++!53 = !DILocation(line: 26, column: 10, scope: !28, inlinedAt: !29)
|
|
|
++!54 = !DILocation(line: 7, column: 7, scope: !24, inlinedAt: !55)
|
|
|
++!55 = distinct !DILocation(line: 27, column: 3, scope: !28, inlinedAt: !29)
|
|
|
++!56 = !DILocation(line: 8, column: 7, scope: !24, inlinedAt: !55)
|
|
|
++!57 = !DILocation(line: 11, column: 18, scope: !24, inlinedAt: !55)
|
|
|
++!58 = !DILocation(line: 11, column: 13, scope: !24, inlinedAt: !55)
|
|
|
++!59 = !DILocation(line: 11, column: 8, scope: !24, inlinedAt: !55)
|
|
|
++!60 = !DILocation(line: 11, column: 3, scope: !24, inlinedAt: !55)
|
|
|
++!61 = !DILocation(line: 11, column: 11, scope: !24, inlinedAt: !55)
|
|
|
++!62 = !DILocation(line: 12, column: 18, scope: !24, inlinedAt: !55)
|
|
|
++!63 = !DILocation(line: 12, column: 10, scope: !24, inlinedAt: !55)
|
|
|
++!64 = !DILocation(line: 13, column: 1, scope: !24, inlinedAt: !55)
|
|
|
++!65 = !DILocation(line: 28, column: 10, scope: !28, inlinedAt: !29)
|
|
|
++!66 = !DILocation(line: 32, column: 9, scope: !30)
|
|
|
++!67 = !DILocation(line: 33, column: 45, scope: !30)
|
|
|
++!68 = !DILocation(line: 34, column: 28, scope: !30)
|
|
|
++!69 = !DILocation(line: 34, column: 18, scope: !30)
|
|
|
++!70 = !DILocation(line: 34, column: 26, scope: !30)
|
|
|
++!71 = !DILocation(line: 35, column: 10, scope: !30)
|
|
|
++!72 = !DILocation(line: 35, column: 3, scope: !30)
|