From 54e1d02715747ee81585bfd23e96a1f4956dbf66 Mon Sep 17 00:00:00 2001 From: Yong He Date: Tue, 7 Oct 2025 08:53:36 -0700 Subject: Fix a bug that causes a struct field to be initialized twice. (#8619) We insert field initialization logic at the beginning of every ctor in `synthesizeCtorBody`, but then immediately inserts another round of initialization again for explicit ctors in `maybeInsertDefaultInitExpr`, both called from `SemanticsDeclBodyVisitor::visitAggTypeDecl` right next to each other. The fix is to remove `maybeInsertDefaultInitExpr`. This change also enhances the address aliasing analysis, so that for the following case: ``` this->member1 = 0; this->member2 = 0; this->member1 = param; ``` We can still remove the first assignment to `this->member1` despite seeing `this->member2=0`, since it is easy to know that `this->member2` cannot alias with `this->member1`. Closes #8600. --- .../func-resource-result/init-copy-eliminate.slang | 40 ++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 tests/optimization/func-resource-result/init-copy-eliminate.slang (limited to 'tests') diff --git a/tests/optimization/func-resource-result/init-copy-eliminate.slang b/tests/optimization/func-resource-result/init-copy-eliminate.slang new file mode 100644 index 000000000..c7c8eadcf --- /dev/null +++ b/tests/optimization/func-resource-result/init-copy-eliminate.slang @@ -0,0 +1,40 @@ +//TEST:SIMPLE(filecheck=CHECK):-target cuda -entry computeMain -stage compute + +// Test on a regression that caused a field to be initialized twice in the ctor. + +// CHECK-COUNT-1: callOnce{{.*}}(int(1000)) +// CHECK-COUNT-1: {{.*}}->origin_0 = +int callOnce(int x) +{ + *result += 1.0f; // cause some side effect so the call is not eliminated + return 999; +} + +public struct Ray +{ + public int calledOnce = callOnce(1000); + public float3 origin = {}; + public float t_min = 0; + public float3 dir = {}; + public float t_max = 0; + + public __init(float3 origin, float3 dir, float t_min = 0.f, float t_max = 1000.0) + { + this.origin = origin; + this.dir = dir; + this.t_min = t_min; + this.t_max = t_max; + } + + public RayDesc to_ray_desc() { return { origin, t_min, dir, t_max }; } +}; + +uniform float* result; + +[numthreads(1,1,1)] +void computeMain() +{ + Ray r = Ray(float3(1,2,3), float3(4,5,6)); + RayDesc rd = r.to_ray_desc(); + *result = rd.Direction.x; +} -- cgit v1.2.3