microsoft / microsoft/DirectXShaderCompiler

Reading uninitialized value in dynamic loop produces undef with no error/warning

Open
#3,811 0 comments 7 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

validation
Dominant language
C++
Stars
3.7k
Forks
900
Avg merge
2d 11h
Merged PRs (30d)
44

Description

Reading an uninitialized value in a dynamic loop produces no error or warning if the value is also written to in the loop (because undef is permitted in phi nodes, it seems).

source.hlsl:

StructuredBuffer<float> values : register(t0,space0);

void Accumulate(int count, out float result)
{
	// result += values[0];  // <-- This will fail validation and produce an error message
	for (int i = 0; i < count; i++)
		result += values[i];  // <-- This will not
}

float main (int count : IN) : OUT
{
	float result = 0.0;
	Accumulate(count, result);
	return result;
}

dxc.exe -T vs_6_0 source.hlsl

Output:

define void @main() {
  %1 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 0, i32 0, i32 0, i1 false)  ; CreateHandle(resourceClass,rangeId,index,nonUniformIndex)
  %2 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 0, i32 undef)  ; LoadInput(inputSigId,rowIndex,colIndex,gsVertexAxis)
  %3 = icmp sgt i32 %2, 0
  br i1 %3, label %4, label %14

; <label>:4                                       ; preds = %0
  br label %5

; <label>:5                                       ; preds = %5, %4
  %6 = phi i32 [ %11, %5 ], [ 0, %4 ]
  %7 = phi float [ %10, %5 ], [ undef, %4 ]
  %8 = call %dx.types.ResRet.f32 @dx.op.bufferLoad.f32(i32 68, %dx.types.Handle %1, i32 %6, i32 0)  ; BufferLoad(srv,index,wot)
  %9 = extractvalue %dx.types.ResRet.f32 %8, 0
  %10 = fadd fast float %9, %7
  %11 = add nuw nsw i32 %6, 1
  %12 = icmp eq i32 %11, %2
  br i1 %12, label %13, label %5

; <label>:13                                      ; preds = %5
  br label %14

; <label>:14                                      ; preds = %13, %0
  %15 = phi float [ undef, %0 ], [ %10, %13 ]
  call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 0, float %15)  ; StoreOutput(outputSigId,rowIndex,colIndex,value)
  ret void
}

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the example in source.hlsl with dxc.exe -T vs_6_0 source.hlsl and compare the dynamic-loop case with the direct access case. Trace the compiler validation path for undef values in the generated phi nodes; done means the loop case produces the appropriate validation error or warning instead of silently emitting undef.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.