diff --git a/tools/clang/lib/SPIRV/SpirvEmitter.cpp b/tools/clang/lib/SPIRV/SpirvEmitter.cpp index e96bc44c1..8d142f2eb 100644 --- a/tools/clang/lib/SPIRV/SpirvEmitter.cpp +++ b/tools/clang/lib/SPIRV/SpirvEmitter.cpp @@ -5349,14 +5349,18 @@ void SpirvEmitter::condenseVectorElementExpr( const HLSLVectorElementExpr *expr, const Expr **basePtr, hlsl::VectorMemberAccessPositions *flattenedAccessor) { llvm::SmallVector accessors; - accessors.push_back(expr->getEncodedElementAccess()); + *basePtr = expr; - // Recursively descending until we find the true base vector. In the - // meanwhile, collecting accessors in the reverse order. - *basePtr = expr->getBase(); + // Recursively descending until we find the true base vector (the base vector + // that does not have a base vector). In the meanwhile, collecting accessors + // in the reverse order. + // Example: for myVector.yxwz.yxz.xx.yx, the true base is 'myVector'. while (const auto *vecElemBase = dyn_cast(*basePtr)) { accessors.push_back(vecElemBase->getEncodedElementAccess()); *basePtr = vecElemBase->getBase(); + // We need to skip any number of parentheses around swizzling at any level. + while (const auto *parenExpr = dyn_cast(*basePtr)) + *basePtr = parenExpr->getSubExpr(); } *flattenedAccessor = accessors.back(); diff --git a/tools/clang/test/CodeGenSPIRV/op.vector.swizzle.hlsl b/tools/clang/test/CodeGenSPIRV/op.vector.swizzle.hlsl index eb5eef293..d1e621487 100644 --- a/tools/clang/test/CodeGenSPIRV/op.vector.swizzle.hlsl +++ b/tools/clang/test/CodeGenSPIRV/op.vector.swizzle.hlsl @@ -136,4 +136,26 @@ void main() { // CHECK-NEXT: [[ac3:%\d+]] = OpAccessChain %_ptr_Function_float %v4f2 %int_3 // CHECK-NEXT: OpStore [[ac3]] [[e0]] v4f2.w.x.x.x = v4f1.y.x.x.x; // continuously selecting one element + + // Continuous selection with parentheses + +// CHECK-NEXT: [[ptr:%\d+]] = OpAccessChain %_ptr_Function_float %v4f1 %int_3 +// CHECK-NEXT: OpStore [[ptr]] %float_5 + (v4f1.xwzy.yxz).x = 5.0f; + +// CHECK-NEXT: [[ptr:%\d+]] = OpAccessChain %_ptr_Function_float %v4f1 %int_3 +// CHECK-NEXT: OpStore [[ptr]] %float_5 + (v4f1.xwzy).yxz.x = 5.0f; + +// CHECK-NEXT: [[ptr:%\d+]] = OpAccessChain %_ptr_Function_float %v4f1 %int_3 +// CHECK-NEXT: OpStore [[ptr]] %float_5 + ((v4f1.xwzy).yxz).x = 5.0f; + +// CHECK-NEXT: [[ptr:%\d+]] = OpAccessChain %_ptr_Function_float %v4f1 %int_3 +// CHECK-NEXT: OpStore [[ptr]] %float_5 + (((v4f1.xwzy).yxz).x) = 5.0f; + +// CHECK-NEXT: [[ptr:%\d+]] = OpAccessChain %_ptr_Function_float %v4f1 %int_3 +// CHECK-NEXT: OpStore [[ptr]] %float_5 + ((((v4f1.xwzy).yxz)).x) = 5.0f; } \ No newline at end of file