[spirv] Handle parentheses in vector swizzling. (#2066)
This commit is contained in:
Родитель
e172d50d71
Коммит
327e37077e
|
@ -5349,14 +5349,18 @@ void SpirvEmitter::condenseVectorElementExpr(
|
||||||
const HLSLVectorElementExpr *expr, const Expr **basePtr,
|
const HLSLVectorElementExpr *expr, const Expr **basePtr,
|
||||||
hlsl::VectorMemberAccessPositions *flattenedAccessor) {
|
hlsl::VectorMemberAccessPositions *flattenedAccessor) {
|
||||||
llvm::SmallVector<hlsl::VectorMemberAccessPositions, 2> accessors;
|
llvm::SmallVector<hlsl::VectorMemberAccessPositions, 2> accessors;
|
||||||
accessors.push_back(expr->getEncodedElementAccess());
|
*basePtr = expr;
|
||||||
|
|
||||||
// Recursively descending until we find the true base vector. In the
|
// Recursively descending until we find the true base vector (the base vector
|
||||||
// meanwhile, collecting accessors in the reverse order.
|
// that does not have a base vector). In the meanwhile, collecting accessors
|
||||||
*basePtr = expr->getBase();
|
// in the reverse order.
|
||||||
|
// Example: for myVector.yxwz.yxz.xx.yx, the true base is 'myVector'.
|
||||||
while (const auto *vecElemBase = dyn_cast<HLSLVectorElementExpr>(*basePtr)) {
|
while (const auto *vecElemBase = dyn_cast<HLSLVectorElementExpr>(*basePtr)) {
|
||||||
accessors.push_back(vecElemBase->getEncodedElementAccess());
|
accessors.push_back(vecElemBase->getEncodedElementAccess());
|
||||||
*basePtr = vecElemBase->getBase();
|
*basePtr = vecElemBase->getBase();
|
||||||
|
// We need to skip any number of parentheses around swizzling at any level.
|
||||||
|
while (const auto *parenExpr = dyn_cast<ParenExpr>(*basePtr))
|
||||||
|
*basePtr = parenExpr->getSubExpr();
|
||||||
}
|
}
|
||||||
|
|
||||||
*flattenedAccessor = accessors.back();
|
*flattenedAccessor = accessors.back();
|
||||||
|
|
|
@ -136,4 +136,26 @@ void main() {
|
||||||
// CHECK-NEXT: [[ac3:%\d+]] = OpAccessChain %_ptr_Function_float %v4f2 %int_3
|
// CHECK-NEXT: [[ac3:%\d+]] = OpAccessChain %_ptr_Function_float %v4f2 %int_3
|
||||||
// CHECK-NEXT: OpStore [[ac3]] [[e0]]
|
// CHECK-NEXT: OpStore [[ac3]] [[e0]]
|
||||||
v4f2.w.x.x.x = v4f1.y.x.x.x; // continuously selecting one element
|
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;
|
||||||
}
|
}
|
Загрузка…
Ссылка в новой задаче