-
Notifications
You must be signed in to change notification settings - Fork 696
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix invalid IR from scalarrepl-param-hlsl in ReplaceConstantWithInst
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.
- Loading branch information
Showing
3 changed files
with
337 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
46 changes: 46 additions & 0 deletions
46
tools/clang/test/DXC/scalarrepl-param-hlsl-const-to-local-and-back.hlsl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
// RUN: %dxc -T ps_6_2 %s | 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. | ||
|
||
// This test is expected to fail with "error: Loop must have a break." | ||
// XFAIL: * | ||
|
||
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; | ||
} |
Oops, something went wrong.