Implement compile-time optimization for min() and max().

`evaluate_intrinsic_1_of_type` was rewritten and now supports up to
three arguments. The following APIs are now optimizable:

	$genType min($genType x, $genType y);
	$genType min($genType x, float y);
	$genHType min($genHType x, $genHType y);
	$genHType min($genHType x, half y);
	$genIType min($genIType x, $genIType y);
	$genIType min($genIType x, int y);
	$genType max($genType x, $genType y);
	$genType max($genType x, float y);
	$genHType max($genHType x, $genHType y);
	$genHType max($genHType x, half y);
	$genIType max($genIType x, $genIType y);
	$genIType max($genIType x, int y);

Change-Id: I0a6467fb60b008b61e8b6a7affaebfcb15f5f7a9
Bug: skia:12034
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/412057
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
This commit is contained in:
John Stiles 2021-05-25 09:46:08 -04:00 committed by Skia Commit-Bot
parent 5ccb4c1b1d
commit 7f17d36c2c
17 changed files with 798 additions and 320 deletions

View File

@ -4,12 +4,22 @@ uniform half4 colorGreen, colorRed;
half4 main(float2 coords) { half4 main(float2 coords) {
half4 expectedA = half4(0.5, 0.5, 0.75, 2.25); half4 expectedA = half4(0.5, 0.5, 0.75, 2.25);
half4 expectedB = half4(0, 1, 0.75, 2.25); half4 expectedB = half4(0, 1, 0.75, 2.25);
const half4 constVal = half4(-1.25, 0, 0.75, 2.25);
const half4 constGreen = half4(0, 1, 0, 1);
return (max(testInputs.x, 0.5) == expectedA.x && return (max(testInputs.x, 0.5) == expectedA.x &&
max(testInputs.xy, 0.5) == expectedA.xy && max(testInputs.xy, 0.5) == expectedA.xy &&
max(testInputs.xyz, 0.5) == expectedA.xyz && max(testInputs.xyz, 0.5) == expectedA.xyz &&
max(testInputs.xyzw, 0.5) == expectedA.xyzw && max(testInputs.xyzw, 0.5) == expectedA.xyzw &&
max(constVal.x, 0.5) == expectedA.x &&
max(constVal.xy, 0.5) == expectedA.xy &&
max(constVal.xyz, 0.5) == expectedA.xyz &&
max(constVal.xyzw, 0.5) == expectedA.xyzw &&
max(testInputs.x, colorGreen.x) == expectedB.x && max(testInputs.x, colorGreen.x) == expectedB.x &&
max(testInputs.xy, colorGreen.xy) == expectedB.xy && max(testInputs.xy, colorGreen.xy) == expectedB.xy &&
max(testInputs.xyz, colorGreen.xyz) == expectedB.xyz && max(testInputs.xyz, colorGreen.xyz) == expectedB.xyz &&
max(testInputs.xyzw, colorGreen.xyzw) == expectedB.xyzw) ? colorGreen : colorRed; max(testInputs.xyzw, colorGreen.xyzw) == expectedB.xyzw &&
max(constVal.x, constGreen.x) == expectedB.x &&
max(constVal.xy, constGreen.xy) == expectedB.xy &&
max(constVal.xyz, constGreen.xyz) == expectedB.xyz &&
max(constVal.xyzw, constGreen.xyzw) == expectedB.xyzw) ? colorGreen : colorRed;
} }

View File

@ -4,15 +4,25 @@ uniform half4 colorGreen, colorRed;
half4 main(float2 coords) { half4 main(float2 coords) {
int4 intValues = int4(testInputs * 100); int4 intValues = int4(testInputs * 100);
int4 intGreen = int4(colorGreen * 100); int4 intGreen = int4(colorGreen * 100);
const int4 constVal = int4(-125, 0, 75, 225);
const int4 constGreen = int4(0, 100, 0, 100);
int4 expectedA = int4(50, 50, 75, 225); int4 expectedA = int4(50, 50, 75, 225);
int4 expectedB = int4(0, 100, 75, 225); int4 expectedB = int4(0, 100, 75, 225);
return (max(intValues.x, 50) == expectedA.x && return (max(intValues.x, 50) == expectedA.x &&
max(intValues.xy, 50) == expectedA.xy && max(intValues.xy, 50) == expectedA.xy &&
max(intValues.xyz, 50) == expectedA.xyz && max(intValues.xyz, 50) == expectedA.xyz &&
max(intValues.xyzw, 50) == expectedA.xyzw && max(intValues.xyzw, 50) == expectedA.xyzw &&
max(intValues.x, intGreen.x) == expectedB.x && max(constVal.x, 50) == expectedA.x &&
max(intValues.xy, intGreen.xy) == expectedB.xy && max(constVal.xy, 50) == expectedA.xy &&
max(intValues.xyz, intGreen.xyz) == expectedB.xyz && max(constVal.xyz, 50) == expectedA.xyz &&
max(intValues.xyzw, intGreen.xyzw) == expectedB.xyzw) ? colorGreen : colorRed; max(constVal.xyzw, 50) == expectedA.xyzw &&
max(intValues.x, intGreen.x) == expectedB.x &&
max(intValues.xy, intGreen.xy) == expectedB.xy &&
max(intValues.xyz, intGreen.xyz) == expectedB.xyz &&
max(intValues.xyzw, intGreen.xyzw) == expectedB.xyzw &&
max(constVal.x, constGreen.x) == expectedB.x &&
max(constVal.xy, constGreen.xy) == expectedB.xy &&
max(constVal.xyz, constGreen.xyz) == expectedB.xyz &&
max(constVal.xyzw, constGreen.xyzw) == expectedB.xyzw) ? colorGreen : colorRed;
} }

View File

@ -4,12 +4,22 @@ uniform half4 colorGreen, colorRed;
half4 main(float2 coords) { half4 main(float2 coords) {
half4 expectedA = half4(-1.25, 0, 0.5, 0.5); half4 expectedA = half4(-1.25, 0, 0.5, 0.5);
half4 expectedB = half4(-1.25, 0, 0, 1); half4 expectedB = half4(-1.25, 0, 0, 1);
const half4 constVal = half4(-1.25, 0, 0.75, 2.25);
const half4 constGreen = half4(0, 1, 0, 1);
return (min(testInputs.x, 0.5) == expectedA.x && return (min(testInputs.x, 0.5) == expectedA.x &&
min(testInputs.xy, 0.5) == expectedA.xy && min(testInputs.xy, 0.5) == expectedA.xy &&
min(testInputs.xyz, 0.5) == expectedA.xyz && min(testInputs.xyz, 0.5) == expectedA.xyz &&
min(testInputs.xyzw, 0.5) == expectedA.xyzw && min(testInputs.xyzw, 0.5) == expectedA.xyzw &&
min(constVal.x, 0.5) == expectedA.x &&
min(constVal.xy, 0.5) == expectedA.xy &&
min(constVal.xyz, 0.5) == expectedA.xyz &&
min(constVal.xyzw, 0.5) == expectedA.xyzw &&
min(testInputs.x, colorGreen.x) == expectedB.x && min(testInputs.x, colorGreen.x) == expectedB.x &&
min(testInputs.xy, colorGreen.xy) == expectedB.xy && min(testInputs.xy, colorGreen.xy) == expectedB.xy &&
min(testInputs.xyz, colorGreen.xyz) == expectedB.xyz && min(testInputs.xyz, colorGreen.xyz) == expectedB.xyz &&
min(testInputs.xyzw, colorGreen.xyzw) == expectedB.xyzw) ? colorGreen : colorRed; min(testInputs.xyzw, colorGreen.xyzw) == expectedB.xyzw &&
min(constVal.x, constGreen.x) == expectedB.x &&
min(constVal.xy, constGreen.xy) == expectedB.xy &&
min(constVal.xyz, constGreen.xyz) == expectedB.xyz &&
min(constVal.xyzw, constGreen.xyzw) == expectedB.xyzw) ? colorGreen : colorRed;
} }

View File

@ -4,15 +4,25 @@ uniform half4 colorGreen, colorRed;
half4 main(float2 coords) { half4 main(float2 coords) {
int4 intValues = int4(testInputs * 100); int4 intValues = int4(testInputs * 100);
int4 intGreen = int4(colorGreen * 100); int4 intGreen = int4(colorGreen * 100);
const int4 constVal = int4(-125, 0, 75, 225);
const int4 constGreen = int4(0, 100, 0, 100);
int4 expectedA = int4(-125, 0, 50, 50); int4 expectedA = int4(-125, 0, 50, 50);
int4 expectedB = int4(-125, 0, 0, 100); int4 expectedB = int4(-125, 0, 0, 100);
return (min(intValues.x, 50) == expectedA.x && return (min(intValues.x, 50) == expectedA.x &&
min(intValues.xy, 50) == expectedA.xy && min(intValues.xy, 50) == expectedA.xy &&
min(intValues.xyz, 50) == expectedA.xyz && min(intValues.xyz, 50) == expectedA.xyz &&
min(intValues.xyzw, 50) == expectedA.xyzw && min(intValues.xyzw, 50) == expectedA.xyzw &&
min(intValues.x, intGreen.x) == expectedB.x && min(constVal.x, 50) == expectedA.x &&
min(intValues.xy, intGreen.xy) == expectedB.xy && min(constVal.xy, 50) == expectedA.xy &&
min(intValues.xyz, intGreen.xyz) == expectedB.xyz && min(constVal.xyz, 50) == expectedA.xyz &&
min(intValues.xyzw, intGreen.xyzw) == expectedB.xyzw) ? colorGreen : colorRed; min(constVal.xyzw, 50) == expectedA.xyzw &&
min(intValues.x, intGreen.x) == expectedB.x &&
min(intValues.xy, intGreen.xy) == expectedB.xy &&
min(intValues.xyz, intGreen.xyz) == expectedB.xyz &&
min(intValues.xyzw, intGreen.xyzw) == expectedB.xyzw &&
min(constVal.x, constGreen.x) == expectedB.x &&
min(constVal.xy, constGreen.xy) == expectedB.xy &&
min(constVal.xyz, constGreen.xyz) == expectedB.xyz &&
min(constVal.xyzw, constGreen.xyzw) == expectedB.xyzw) ? colorGreen : colorRed;
} }

View File

@ -94,48 +94,101 @@ static std::unique_ptr<Expression> optimize_comparison(const Context& context,
} }
template <typename T> template <typename T>
static std::unique_ptr<Expression> evaluate_intrinsic_1_of_type(const Context& context, static std::unique_ptr<Expression> evaluate_n_way_intrinsic_of_type(
const Expression* arg, const Context& context,
const std::function<T(T)>& eval) { const Expression* arg0,
arg = ConstantFolder::GetConstantValueForVariable(*arg); const Expression* arg1,
SkASSERT(arg); const Expression* arg2,
const Type& vecType = arg->type(); const std::function<T(T, T, T)>& eval) {
// Takes up to three arguments and evaluates them in tandem, equivalent to constructing a new
// vector containing the results from:
// eval(arg0.x, arg1.x, arg2.x),
// eval(arg0.y, arg1.y, arg2.y),
// eval(arg0.w, arg1.z, arg2.z),
// eval(arg0.z, arg1.w, arg2.w)
//
// If an argument is null, zero is passed to the evaluation function. If arg1 or arg2 contains a
// scalar, it is interpreted as a vector containing the same value for every component.
arg0 = ConstantFolder::GetConstantValueForVariable(*arg0);
SkASSERT(arg0);
const Type& vecType = arg0->type();
const Type& type = vecType.componentType(); const Type& type = vecType.componentType();
if (arg1) {
arg1 = ConstantFolder::GetConstantValueForVariable(*arg1);
SkASSERT(arg1);
SkASSERT(arg1->type().componentType() == type);
}
if (arg2) {
arg2 = ConstantFolder::GetConstantValueForVariable(*arg2);
SkASSERT(arg2);
SkASSERT(arg2->type().componentType() == type);
}
ExpressionArray array; ExpressionArray array;
array.reserve_back(vecType.columns()); array.reserve_back(vecType.columns());
int arg0Index = 0;
int arg1Index = 0;
int arg2Index = 0;
for (int index = 0; index < vecType.columns(); ++index) { for (int index = 0; index < vecType.columns(); ++index) {
const Expression* subexpr = arg->getConstantSubexpression(index); const Expression* arg0Subexpr = arg0->getConstantSubexpression(arg0Index);
SkASSERT(subexpr); arg0Index += arg0->type().isVector() ? 1 : 0;
T value = eval(subexpr->as<Literal<T>>().value()); SkASSERT(arg0Subexpr);
const Expression* arg1Subexpr = nullptr;
if (arg1) {
arg1Subexpr = arg1->getConstantSubexpression(arg1Index);
arg1Index += arg1->type().isVector() ? 1 : 0;
SkASSERT(arg1Subexpr);
}
const Expression* arg2Subexpr = nullptr;
if (arg2) {
arg2Subexpr = arg2->getConstantSubexpression(arg1Index);
arg2Index += arg2->type().isVector() ? 1 : 0;
SkASSERT(arg2Subexpr);
}
T value = eval(arg0Subexpr->as<Literal<T>>().value(),
arg1Subexpr ? arg1Subexpr->as<Literal<T>>().value() : T{},
arg2Subexpr ? arg2Subexpr->as<Literal<T>>().value() : T{});
if constexpr (std::is_floating_point<T>::value) { if constexpr (std::is_floating_point<T>::value) {
// If evaluation of the intrinsic yields a non-finite value, do not optimize. // If evaluation of the intrinsic yields a non-finite value, do not optimize.
if (!isfinite(value)) { if (!isfinite(value)) {
return nullptr; return nullptr;
} }
} }
array.push_back(Literal<T>::Make(arg->fOffset, value, &type));
array.push_back(Literal<T>::Make(arg0Subexpr->fOffset, value, &type));
} }
return ConstructorCompound::Make(context, arg->fOffset, vecType, std::move(array)); return ConstructorCompound::Make(context, arg0->fOffset, vecType, std::move(array));
} }
template <typename FN> template <typename FN>
static std::unique_ptr<Expression> evaluate_intrinsic_numeric1(const Context& context, static std::unique_ptr<Expression> evaluate_intrinsic_numeric1(const Context& context,
const ExpressionArray& arguments, const ExpressionArray& arguments,
const FN& evaluate) { const FN& eval) {
SkASSERT(arguments.size() == 1); SkASSERT(arguments.size() == 1);
const Type& type = arguments.front()->type().componentType(); const Type& type = arguments.front()->type().componentType();
if (type.isFloat()) { if (type.isFloat()) {
return evaluate_intrinsic_1_of_type<float>(context, arguments.front().get(), evaluate); return evaluate_n_way_intrinsic_of_type<float>(
} else if (type.isInteger()) { context, arguments.front().get(), /*arg1=*/nullptr, /*arg2=*/nullptr,
return evaluate_intrinsic_1_of_type<SKSL_INT>(context, arguments.front().get(), evaluate); [&eval](float a, float, float) { return eval(a); });
} else {
SkDEBUGFAILF("unsupported type %s", type.description().c_str());
return nullptr;
} }
if (type.isInteger()) {
return evaluate_n_way_intrinsic_of_type<SKSL_INT>(
context, arguments.front().get(), /*arg1=*/nullptr, /*arg2=*/nullptr,
[&eval](SKSL_INT a, SKSL_INT, SKSL_INT) { return eval(a); });
}
SkDEBUGFAILF("unsupported type %s", type.description().c_str());
return nullptr;
} }
static std::unique_ptr<Expression> evaluate_intrinsic_float1( static std::unique_ptr<Expression> evaluate_intrinsic_float1(
@ -146,11 +199,13 @@ static std::unique_ptr<Expression> evaluate_intrinsic_float1(
const Type& type = arguments.front()->type().componentType(); const Type& type = arguments.front()->type().componentType();
if (type.isFloat()) { if (type.isFloat()) {
return evaluate_intrinsic_1_of_type<float>(context, arguments.front().get(), eval); return evaluate_n_way_intrinsic_of_type<float>(
} else { context, arguments.front().get(), /*arg1=*/nullptr, /*arg2=*/nullptr,
SkDEBUGFAILF("unsupported type %s", type.description().c_str()); [&eval](float a, float, float) { return eval(a); });
return nullptr;
} }
SkDEBUGFAILF("unsupported type %s", type.description().c_str());
return nullptr;
} }
static std::unique_ptr<Expression> evaluate_intrinsic_bool1(const Context& context, static std::unique_ptr<Expression> evaluate_intrinsic_bool1(const Context& context,
@ -160,11 +215,35 @@ static std::unique_ptr<Expression> evaluate_intrinsic_bool1(const Context& conte
const Type& type = arguments.front()->type().componentType(); const Type& type = arguments.front()->type().componentType();
if (type.isBoolean()) { if (type.isBoolean()) {
return evaluate_intrinsic_1_of_type<bool>(context, arguments.front().get(), eval); return evaluate_n_way_intrinsic_of_type<bool>(
} else { context, arguments.front().get(), /*arg1=*/nullptr, /*arg2=*/nullptr,
SkDEBUGFAILF("unsupported type %s", type.description().c_str()); [&eval](bool a, bool, bool) { return eval(a); });
return nullptr;
} }
SkDEBUGFAILF("unsupported type %s", type.description().c_str());
return nullptr;
}
template <typename FN>
static std::unique_ptr<Expression> evaluate_pairwise_intrinsic(const Context& context,
const ExpressionArray& arguments,
const FN& eval) {
SkASSERT(arguments.size() == 2);
const Type& type = arguments.front()->type().componentType();
if (type.isFloat()) {
return evaluate_n_way_intrinsic_of_type<float>(
context, arguments[0].get(), arguments[1].get(), /*arg2=*/nullptr,
[&eval](float a, float b, float) { return eval(a, b); });
}
if (type.isInteger()) {
return evaluate_n_way_intrinsic_of_type<SKSL_INT>(
context, arguments[0].get(), arguments[1].get(), /*arg2=*/nullptr,
[&eval](SKSL_INT a, SKSL_INT b, SKSL_INT) { return eval(a, b); });
}
SkDEBUGFAILF("unsupported type %s", type.description().c_str());
return nullptr;
} }
static std::unique_ptr<Expression> optimize_intrinsic_call(const Context& context, static std::unique_ptr<Expression> optimize_intrinsic_call(const Context& context,
@ -271,6 +350,12 @@ static std::unique_ptr<Expression> optimize_intrinsic_call(const Context& contex
case k_degrees_IntrinsicKind: case k_degrees_IntrinsicKind:
return evaluate_intrinsic_float1(context, arguments, return evaluate_intrinsic_float1(context, arguments,
[](float a) { return a * 57.2957795; }); [](float a) { return a * 57.2957795; });
case k_min_IntrinsicKind:
return evaluate_pairwise_intrinsic(context, arguments,
[](auto a, auto b) { return (a < b) ? a : b; });
case k_max_IntrinsicKind:
return evaluate_pairwise_intrinsic(context, arguments,
[](auto a, auto b) { return (a > b) ? a : b; });
default: default:
return nullptr; return nullptr;
} }

View File

@ -47,30 +47,48 @@ OpDecorate %68 RelaxedPrecision
OpDecorate %77 RelaxedPrecision OpDecorate %77 RelaxedPrecision
OpDecorate %78 RelaxedPrecision OpDecorate %78 RelaxedPrecision
OpDecorate %79 RelaxedPrecision OpDecorate %79 RelaxedPrecision
OpDecorate %88 RelaxedPrecision OpDecorate %86 RelaxedPrecision
OpDecorate %89 RelaxedPrecision OpDecorate %87 RelaxedPrecision
OpDecorate %92 RelaxedPrecision OpDecorate %92 RelaxedPrecision
OpDecorate %93 RelaxedPrecision OpDecorate %93 RelaxedPrecision
OpDecorate %94 RelaxedPrecision OpDecorate %94 RelaxedPrecision
OpDecorate %95 RelaxedPrecision OpDecorate %100 RelaxedPrecision
OpDecorate %101 RelaxedPrecision
OpDecorate %102 RelaxedPrecision OpDecorate %102 RelaxedPrecision
OpDecorate %103 RelaxedPrecision
OpDecorate %105 RelaxedPrecision
OpDecorate %106 RelaxedPrecision
OpDecorate %107 RelaxedPrecision
OpDecorate %108 RelaxedPrecision OpDecorate %108 RelaxedPrecision
OpDecorate %116 RelaxedPrecision OpDecorate %116 RelaxedPrecision
OpDecorate %117 RelaxedPrecision OpDecorate %117 RelaxedPrecision
OpDecorate %119 RelaxedPrecision
OpDecorate %120 RelaxedPrecision OpDecorate %120 RelaxedPrecision
OpDecorate %121 RelaxedPrecision OpDecorate %121 RelaxedPrecision
OpDecorate %122 RelaxedPrecision OpDecorate %122 RelaxedPrecision
OpDecorate %123 RelaxedPrecision
OpDecorate %130 RelaxedPrecision OpDecorate %130 RelaxedPrecision
OpDecorate %132 RelaxedPrecision OpDecorate %131 RelaxedPrecision
OpDecorate %133 RelaxedPrecision OpDecorate %133 RelaxedPrecision
OpDecorate %142 RelaxedPrecision OpDecorate %134 RelaxedPrecision
OpDecorate %135 RelaxedPrecision
OpDecorate %136 RelaxedPrecision
OpDecorate %144 RelaxedPrecision
OpDecorate %145 RelaxedPrecision OpDecorate %145 RelaxedPrecision
OpDecorate %146 RelaxedPrecision OpDecorate %147 RelaxedPrecision
OpDecorate %148 RelaxedPrecision
OpDecorate %149 RelaxedPrecision
OpDecorate %150 RelaxedPrecision
OpDecorate %158 RelaxedPrecision
OpDecorate %160 RelaxedPrecision
OpDecorate %161 RelaxedPrecision
OpDecorate %167 RelaxedPrecision
OpDecorate %168 RelaxedPrecision
OpDecorate %173 RelaxedPrecision
OpDecorate %174 RelaxedPrecision
OpDecorate %175 RelaxedPrecision
OpDecorate %181 RelaxedPrecision
OpDecorate %182 RelaxedPrecision
OpDecorate %183 RelaxedPrecision
OpDecorate %189 RelaxedPrecision
OpDecorate %198 RelaxedPrecision
OpDecorate %201 RelaxedPrecision
OpDecorate %202 RelaxedPrecision
%float = OpTypeFloat 32 %float = OpTypeFloat 32
%v4float = OpTypeVector %float 4 %v4float = OpTypeVector %float 4
%_ptr_Output_v4float = OpTypePointer Output %v4float %_ptr_Output_v4float = OpTypePointer Output %v4float
@ -103,7 +121,11 @@ OpDecorate %146 RelaxedPrecision
%v3float = OpTypeVector %float 3 %v3float = OpTypeVector %float 3
%v3bool = OpTypeVector %bool 3 %v3bool = OpTypeVector %bool 3
%v4bool = OpTypeVector %bool 4 %v4bool = OpTypeVector %bool 4
%92 = OpConstantComposite %v2float %float_0_5 %float_0_5
%100 = OpConstantComposite %v3float %float_0_5 %float_0_5 %float_0_75
%int_1 = OpConstant %int 1 %int_1 = OpConstant %int 1
%173 = OpConstantComposite %v2float %float_0 %float_1
%181 = OpConstantComposite %v3float %float_0 %float_1 %float_0_75
%int_2 = OpConstant %int 2 %int_2 = OpConstant %int 2
%_entrypoint_v = OpFunction %void None %15 %_entrypoint_v = OpFunction %void None %15
%16 = OpLabel %16 = OpLabel
@ -118,7 +140,7 @@ OpFunctionEnd
%25 = OpLabel %25 = OpLabel
%expectedA = OpVariable %_ptr_Function_v4float Function %expectedA = OpVariable %_ptr_Function_v4float Function
%expectedB = OpVariable %_ptr_Function_v4float Function %expectedB = OpVariable %_ptr_Function_v4float Function
%137 = OpVariable %_ptr_Function_v4float Function %193 = OpVariable %_ptr_Function_v4float Function
OpStore %expectedA %31 OpStore %expectedA %31
OpStore %expectedB %34 OpStore %expectedB %34
%37 = OpAccessChain %_ptr_Uniform_v4float %10 %int_0 %37 = OpAccessChain %_ptr_Uniform_v4float %10 %int_0
@ -174,80 +196,156 @@ OpBranch %74
OpSelectionMerge %85 None OpSelectionMerge %85 None
OpBranchConditional %83 %84 %85 OpBranchConditional %83 %84 %85
%84 = OpLabel %84 = OpLabel
%87 = OpAccessChain %_ptr_Uniform_v4float %10 %int_0 %86 = OpLoad %v4float %expectedA
%88 = OpLoad %v4float %87 %87 = OpCompositeExtract %float %86 0
%89 = OpCompositeExtract %float %88 0 %88 = OpFOrdEqual %bool %float_0_5 %87
%90 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%92 = OpLoad %v4float %90
%93 = OpCompositeExtract %float %92 0
%86 = OpExtInst %float %1 FMax %89 %93
%94 = OpLoad %v4float %expectedB
%95 = OpCompositeExtract %float %94 0
%96 = OpFOrdEqual %bool %86 %95
OpBranch %85 OpBranch %85
%85 = OpLabel %85 = OpLabel
%97 = OpPhi %bool %false %74 %96 %84 %89 = OpPhi %bool %false %74 %88 %84
OpSelectionMerge %91 None
OpBranchConditional %89 %90 %91
%90 = OpLabel
%93 = OpLoad %v4float %expectedA
%94 = OpVectorShuffle %v2float %93 %93 0 1
%95 = OpFOrdEqual %v2bool %92 %94
%96 = OpAll %bool %95
OpBranch %91
%91 = OpLabel
%97 = OpPhi %bool %false %85 %96 %90
OpSelectionMerge %99 None OpSelectionMerge %99 None
OpBranchConditional %97 %98 %99 OpBranchConditional %97 %98 %99
%98 = OpLabel %98 = OpLabel
%101 = OpAccessChain %_ptr_Uniform_v4float %10 %int_0 %101 = OpLoad %v4float %expectedA
%102 = OpLoad %v4float %101 %102 = OpVectorShuffle %v3float %101 %101 0 1 2
%103 = OpVectorShuffle %v2float %102 %102 0 1 %103 = OpFOrdEqual %v3bool %100 %102
%104 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1 %104 = OpAll %bool %103
%105 = OpLoad %v4float %104
%106 = OpVectorShuffle %v2float %105 %105 0 1
%100 = OpExtInst %v2float %1 FMax %103 %106
%107 = OpLoad %v4float %expectedB
%108 = OpVectorShuffle %v2float %107 %107 0 1
%109 = OpFOrdEqual %v2bool %100 %108
%110 = OpAll %bool %109
OpBranch %99 OpBranch %99
%99 = OpLabel %99 = OpLabel
%111 = OpPhi %bool %false %85 %110 %98 %105 = OpPhi %bool %false %91 %104 %98
OpSelectionMerge %107 None
OpBranchConditional %105 %106 %107
%106 = OpLabel
%108 = OpLoad %v4float %expectedA
%109 = OpFOrdEqual %v4bool %31 %108
%110 = OpAll %bool %109
OpBranch %107
%107 = OpLabel
%111 = OpPhi %bool %false %99 %110 %106
OpSelectionMerge %113 None OpSelectionMerge %113 None
OpBranchConditional %111 %112 %113 OpBranchConditional %111 %112 %113
%112 = OpLabel %112 = OpLabel
%115 = OpAccessChain %_ptr_Uniform_v4float %10 %int_0 %115 = OpAccessChain %_ptr_Uniform_v4float %10 %int_0
%116 = OpLoad %v4float %115 %116 = OpLoad %v4float %115
%117 = OpVectorShuffle %v3float %116 %116 0 1 2 %117 = OpCompositeExtract %float %116 0
%118 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1 %118 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%119 = OpLoad %v4float %118 %120 = OpLoad %v4float %118
%120 = OpVectorShuffle %v3float %119 %119 0 1 2 %121 = OpCompositeExtract %float %120 0
%114 = OpExtInst %v3float %1 FMax %117 %120 %114 = OpExtInst %float %1 FMax %117 %121
%121 = OpLoad %v4float %expectedB %122 = OpLoad %v4float %expectedB
%122 = OpVectorShuffle %v3float %121 %121 0 1 2 %123 = OpCompositeExtract %float %122 0
%123 = OpFOrdEqual %v3bool %114 %122 %124 = OpFOrdEqual %bool %114 %123
%124 = OpAll %bool %123
OpBranch %113 OpBranch %113
%113 = OpLabel %113 = OpLabel
%125 = OpPhi %bool %false %99 %124 %112 %125 = OpPhi %bool %false %107 %124 %112
OpSelectionMerge %127 None OpSelectionMerge %127 None
OpBranchConditional %125 %126 %127 OpBranchConditional %125 %126 %127
%126 = OpLabel %126 = OpLabel
%129 = OpAccessChain %_ptr_Uniform_v4float %10 %int_0 %129 = OpAccessChain %_ptr_Uniform_v4float %10 %int_0
%130 = OpLoad %v4float %129 %130 = OpLoad %v4float %129
%131 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1 %131 = OpVectorShuffle %v2float %130 %130 0 1
%132 = OpLoad %v4float %131 %132 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%128 = OpExtInst %v4float %1 FMax %130 %132 %133 = OpLoad %v4float %132
%133 = OpLoad %v4float %expectedB %134 = OpVectorShuffle %v2float %133 %133 0 1
%134 = OpFOrdEqual %v4bool %128 %133 %128 = OpExtInst %v2float %1 FMax %131 %134
%135 = OpAll %bool %134 %135 = OpLoad %v4float %expectedB
%136 = OpVectorShuffle %v2float %135 %135 0 1
%137 = OpFOrdEqual %v2bool %128 %136
%138 = OpAll %bool %137
OpBranch %127 OpBranch %127
%127 = OpLabel %127 = OpLabel
%136 = OpPhi %bool %false %113 %135 %126 %139 = OpPhi %bool %false %113 %138 %126
OpSelectionMerge %140 None OpSelectionMerge %141 None
OpBranchConditional %136 %138 %139 OpBranchConditional %139 %140 %141
%138 = OpLabel
%141 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%142 = OpLoad %v4float %141
OpStore %137 %142
OpBranch %140
%139 = OpLabel
%143 = OpAccessChain %_ptr_Uniform_v4float %10 %int_2
%145 = OpLoad %v4float %143
OpStore %137 %145
OpBranch %140
%140 = OpLabel %140 = OpLabel
%146 = OpLoad %v4float %137 %143 = OpAccessChain %_ptr_Uniform_v4float %10 %int_0
OpReturnValue %146 %144 = OpLoad %v4float %143
%145 = OpVectorShuffle %v3float %144 %144 0 1 2
%146 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%147 = OpLoad %v4float %146
%148 = OpVectorShuffle %v3float %147 %147 0 1 2
%142 = OpExtInst %v3float %1 FMax %145 %148
%149 = OpLoad %v4float %expectedB
%150 = OpVectorShuffle %v3float %149 %149 0 1 2
%151 = OpFOrdEqual %v3bool %142 %150
%152 = OpAll %bool %151
OpBranch %141
%141 = OpLabel
%153 = OpPhi %bool %false %127 %152 %140
OpSelectionMerge %155 None
OpBranchConditional %153 %154 %155
%154 = OpLabel
%157 = OpAccessChain %_ptr_Uniform_v4float %10 %int_0
%158 = OpLoad %v4float %157
%159 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%160 = OpLoad %v4float %159
%156 = OpExtInst %v4float %1 FMax %158 %160
%161 = OpLoad %v4float %expectedB
%162 = OpFOrdEqual %v4bool %156 %161
%163 = OpAll %bool %162
OpBranch %155
%155 = OpLabel
%164 = OpPhi %bool %false %141 %163 %154
OpSelectionMerge %166 None
OpBranchConditional %164 %165 %166
%165 = OpLabel
%167 = OpLoad %v4float %expectedB
%168 = OpCompositeExtract %float %167 0
%169 = OpFOrdEqual %bool %float_0 %168
OpBranch %166
%166 = OpLabel
%170 = OpPhi %bool %false %155 %169 %165
OpSelectionMerge %172 None
OpBranchConditional %170 %171 %172
%171 = OpLabel
%174 = OpLoad %v4float %expectedB
%175 = OpVectorShuffle %v2float %174 %174 0 1
%176 = OpFOrdEqual %v2bool %173 %175
%177 = OpAll %bool %176
OpBranch %172
%172 = OpLabel
%178 = OpPhi %bool %false %166 %177 %171
OpSelectionMerge %180 None
OpBranchConditional %178 %179 %180
%179 = OpLabel
%182 = OpLoad %v4float %expectedB
%183 = OpVectorShuffle %v3float %182 %182 0 1 2
%184 = OpFOrdEqual %v3bool %181 %183
%185 = OpAll %bool %184
OpBranch %180
%180 = OpLabel
%186 = OpPhi %bool %false %172 %185 %179
OpSelectionMerge %188 None
OpBranchConditional %186 %187 %188
%187 = OpLabel
%189 = OpLoad %v4float %expectedB
%190 = OpFOrdEqual %v4bool %34 %189
%191 = OpAll %bool %190
OpBranch %188
%188 = OpLabel
%192 = OpPhi %bool %false %180 %191 %187
OpSelectionMerge %196 None
OpBranchConditional %192 %194 %195
%194 = OpLabel
%197 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%198 = OpLoad %v4float %197
OpStore %193 %198
OpBranch %196
%195 = OpLabel
%199 = OpAccessChain %_ptr_Uniform_v4float %10 %int_2
%201 = OpLoad %v4float %199
OpStore %193 %201
OpBranch %196
%196 = OpLabel
%202 = OpLoad %v4float %193
OpReturnValue %202
OpFunctionEnd OpFunctionEnd

View File

@ -6,5 +6,5 @@ uniform vec4 colorRed;
vec4 main() { vec4 main() {
vec4 expectedA = vec4(0.5, 0.5, 0.75, 2.25); vec4 expectedA = vec4(0.5, 0.5, 0.75, 2.25);
vec4 expectedB = vec4(0.0, 1.0, 0.75, 2.25); vec4 expectedB = vec4(0.0, 1.0, 0.75, 2.25);
return ((((((max(testInputs.x, 0.5) == expectedA.x && max(testInputs.xy, 0.5) == expectedA.xy) && max(testInputs.xyz, 0.5) == expectedA.xyz) && max(testInputs, 0.5) == expectedA) && max(testInputs.x, colorGreen.x) == expectedB.x) && max(testInputs.xy, colorGreen.xy) == expectedB.xy) && max(testInputs.xyz, colorGreen.xyz) == expectedB.xyz) && max(testInputs, colorGreen) == expectedB ? colorGreen : colorRed; return ((((((((((((((max(testInputs.x, 0.5) == expectedA.x && max(testInputs.xy, 0.5) == expectedA.xy) && max(testInputs.xyz, 0.5) == expectedA.xyz) && max(testInputs, 0.5) == expectedA) && 0.5 == expectedA.x) && vec2(0.5, 0.5) == expectedA.xy) && vec3(0.5, 0.5, 0.75) == expectedA.xyz) && vec4(0.5, 0.5, 0.75, 2.25) == expectedA) && max(testInputs.x, colorGreen.x) == expectedB.x) && max(testInputs.xy, colorGreen.xy) == expectedB.xy) && max(testInputs.xyz, colorGreen.xyz) == expectedB.xyz) && max(testInputs, colorGreen) == expectedB) && 0.0 == expectedB.x) && vec2(0.0, 1.0) == expectedB.xy) && vec3(0.0, 1.0, 0.75) == expectedB.xyz) && vec4(0.0, 1.0, 0.75, 2.25) == expectedB ? colorGreen : colorRed;
} }

View File

@ -16,6 +16,6 @@ fragment Outputs fragmentMain(Inputs _in [[stage_in]], constant Uniforms& _unifo
(void)_out; (void)_out;
float4 expectedA = float4(0.5, 0.5, 0.75, 2.25); float4 expectedA = float4(0.5, 0.5, 0.75, 2.25);
float4 expectedB = float4(0.0, 1.0, 0.75, 2.25); float4 expectedB = float4(0.0, 1.0, 0.75, 2.25);
_out.sk_FragColor = ((((((max(_uniforms.testInputs.x, 0.5) == expectedA.x && all(max(_uniforms.testInputs.xy, 0.5) == expectedA.xy)) && all(max(_uniforms.testInputs.xyz, 0.5) == expectedA.xyz)) && all(max(_uniforms.testInputs, 0.5) == expectedA)) && max(_uniforms.testInputs.x, _uniforms.colorGreen.x) == expectedB.x) && all(max(_uniforms.testInputs.xy, _uniforms.colorGreen.xy) == expectedB.xy)) && all(max(_uniforms.testInputs.xyz, _uniforms.colorGreen.xyz) == expectedB.xyz)) && all(max(_uniforms.testInputs, _uniforms.colorGreen) == expectedB) ? _uniforms.colorGreen : _uniforms.colorRed; _out.sk_FragColor = ((((((((((((((max(_uniforms.testInputs.x, 0.5) == expectedA.x && all(max(_uniforms.testInputs.xy, 0.5) == expectedA.xy)) && all(max(_uniforms.testInputs.xyz, 0.5) == expectedA.xyz)) && all(max(_uniforms.testInputs, 0.5) == expectedA)) && 0.5 == expectedA.x) && all(float2(0.5, 0.5) == expectedA.xy)) && all(float3(0.5, 0.5, 0.75) == expectedA.xyz)) && all(float4(0.5, 0.5, 0.75, 2.25) == expectedA)) && max(_uniforms.testInputs.x, _uniforms.colorGreen.x) == expectedB.x) && all(max(_uniforms.testInputs.xy, _uniforms.colorGreen.xy) == expectedB.xy)) && all(max(_uniforms.testInputs.xyz, _uniforms.colorGreen.xyz) == expectedB.xyz)) && all(max(_uniforms.testInputs, _uniforms.colorGreen) == expectedB)) && 0.0 == expectedB.x) && all(float2(0.0, 1.0) == expectedB.xy)) && all(float3(0.0, 1.0, 0.75) == expectedB.xyz)) && all(float4(0.0, 1.0, 0.75, 2.25) == expectedB) ? _uniforms.colorGreen : _uniforms.colorRed;
return _out; return _out;
} }

View File

@ -40,9 +40,9 @@ OpDecorate %50 RelaxedPrecision
OpDecorate %52 RelaxedPrecision OpDecorate %52 RelaxedPrecision
OpDecorate %54 RelaxedPrecision OpDecorate %54 RelaxedPrecision
OpDecorate %56 RelaxedPrecision OpDecorate %56 RelaxedPrecision
OpDecorate %160 RelaxedPrecision OpDecorate %216 RelaxedPrecision
OpDecorate %163 RelaxedPrecision OpDecorate %219 RelaxedPrecision
OpDecorate %164 RelaxedPrecision OpDecorate %220 RelaxedPrecision
%float = OpTypeFloat 32 %float = OpTypeFloat 32
%v4float = OpTypeVector %float 4 %v4float = OpTypeVector %float 4
%_ptr_Output_v4float = OpTypePointer Output %v4float %_ptr_Output_v4float = OpTypePointer Output %v4float
@ -79,6 +79,10 @@ OpDecorate %164 RelaxedPrecision
%v3int = OpTypeVector %int 3 %v3int = OpTypeVector %int 3
%v3bool = OpTypeVector %bool 3 %v3bool = OpTypeVector %bool 3
%v4bool = OpTypeVector %bool 4 %v4bool = OpTypeVector %bool 4
%118 = OpConstantComposite %v2int %int_50 %int_50
%126 = OpConstantComposite %v3int %int_50 %int_50 %int_75
%190 = OpConstantComposite %v2int %int_0 %int_100
%198 = OpConstantComposite %v3int %int_0 %int_100 %int_75
%_ptr_Function_v4float = OpTypePointer Function %v4float %_ptr_Function_v4float = OpTypePointer Function %v4float
%int_2 = OpConstant %int 2 %int_2 = OpConstant %int 2
%_entrypoint_v = OpFunction %void None %15 %_entrypoint_v = OpFunction %void None %15
@ -96,7 +100,7 @@ OpFunctionEnd
%intGreen = OpVariable %_ptr_Function_v4int Function %intGreen = OpVariable %_ptr_Function_v4int Function
%expectedA = OpVariable %_ptr_Function_v4int Function %expectedA = OpVariable %_ptr_Function_v4int Function
%expectedB = OpVariable %_ptr_Function_v4int Function %expectedB = OpVariable %_ptr_Function_v4int Function
%154 = OpVariable %_ptr_Function_v4float Function %210 = OpVariable %_ptr_Function_v4float Function
%30 = OpAccessChain %_ptr_Uniform_v4float %10 %int_0 %30 = OpAccessChain %_ptr_Uniform_v4float %10 %int_0
%33 = OpLoad %v4float %30 %33 = OpLoad %v4float %30
%35 = OpVectorTimesScalar %v4float %33 %float_100 %35 = OpVectorTimesScalar %v4float %33 %float_100
@ -174,72 +178,148 @@ OpBranch %101
OpSelectionMerge %111 None OpSelectionMerge %111 None
OpBranchConditional %109 %110 %111 OpBranchConditional %109 %110 %111
%110 = OpLabel %110 = OpLabel
%113 = OpLoad %v4int %intValues %112 = OpLoad %v4int %expectedA
%114 = OpCompositeExtract %int %113 0 %113 = OpCompositeExtract %int %112 0
%115 = OpLoad %v4int %intGreen %114 = OpIEqual %bool %int_50 %113
%116 = OpCompositeExtract %int %115 0
%112 = OpExtInst %int %1 SMax %114 %116
%117 = OpLoad %v4int %expectedB
%118 = OpCompositeExtract %int %117 0
%119 = OpIEqual %bool %112 %118
OpBranch %111 OpBranch %111
%111 = OpLabel %111 = OpLabel
%120 = OpPhi %bool %false %101 %119 %110 %115 = OpPhi %bool %false %101 %114 %110
OpSelectionMerge %122 None OpSelectionMerge %117 None
OpBranchConditional %120 %121 %122 OpBranchConditional %115 %116 %117
%121 = OpLabel %116 = OpLabel
%124 = OpLoad %v4int %intValues %119 = OpLoad %v4int %expectedA
%125 = OpVectorShuffle %v2int %124 %124 0 1 %120 = OpVectorShuffle %v2int %119 %119 0 1
%126 = OpLoad %v4int %intGreen %121 = OpIEqual %v2bool %118 %120
%127 = OpVectorShuffle %v2int %126 %126 0 1 %122 = OpAll %bool %121
%123 = OpExtInst %v2int %1 SMax %125 %127 OpBranch %117
%128 = OpLoad %v4int %expectedB %117 = OpLabel
%129 = OpVectorShuffle %v2int %128 %128 0 1 %123 = OpPhi %bool %false %111 %122 %116
%130 = OpIEqual %v2bool %123 %129 OpSelectionMerge %125 None
%131 = OpAll %bool %130 OpBranchConditional %123 %124 %125
OpBranch %122 %124 = OpLabel
%122 = OpLabel %127 = OpLoad %v4int %expectedA
%132 = OpPhi %bool %false %111 %131 %121 %128 = OpVectorShuffle %v3int %127 %127 0 1 2
OpSelectionMerge %134 None %129 = OpIEqual %v3bool %126 %128
OpBranchConditional %132 %133 %134 %130 = OpAll %bool %129
OpBranch %125
%125 = OpLabel
%131 = OpPhi %bool %false %117 %130 %124
OpSelectionMerge %133 None
OpBranchConditional %131 %132 %133
%132 = OpLabel
%134 = OpLoad %v4int %expectedA
%135 = OpIEqual %v4bool %63 %134
%136 = OpAll %bool %135
OpBranch %133
%133 = OpLabel %133 = OpLabel
%136 = OpLoad %v4int %intValues %137 = OpPhi %bool %false %125 %136 %132
%137 = OpVectorShuffle %v3int %136 %136 0 1 2 OpSelectionMerge %139 None
%138 = OpLoad %v4int %intGreen OpBranchConditional %137 %138 %139
%139 = OpVectorShuffle %v3int %138 %138 0 1 2 %138 = OpLabel
%135 = OpExtInst %v3int %1 SMax %137 %139 %141 = OpLoad %v4int %intValues
%140 = OpLoad %v4int %expectedB %142 = OpCompositeExtract %int %141 0
%141 = OpVectorShuffle %v3int %140 %140 0 1 2 %143 = OpLoad %v4int %intGreen
%142 = OpIEqual %v3bool %135 %141 %144 = OpCompositeExtract %int %143 0
%143 = OpAll %bool %142 %140 = OpExtInst %int %1 SMax %142 %144
OpBranch %134 %145 = OpLoad %v4int %expectedB
%134 = OpLabel %146 = OpCompositeExtract %int %145 0
%144 = OpPhi %bool %false %122 %143 %133 %147 = OpIEqual %bool %140 %146
OpSelectionMerge %146 None OpBranch %139
OpBranchConditional %144 %145 %146 %139 = OpLabel
%145 = OpLabel %148 = OpPhi %bool %false %133 %147 %138
%148 = OpLoad %v4int %intValues OpSelectionMerge %150 None
%149 = OpLoad %v4int %intGreen OpBranchConditional %148 %149 %150
%147 = OpExtInst %v4int %1 SMax %148 %149 %149 = OpLabel
%150 = OpLoad %v4int %expectedB %152 = OpLoad %v4int %intValues
%151 = OpIEqual %v4bool %147 %150 %153 = OpVectorShuffle %v2int %152 %152 0 1
%152 = OpAll %bool %151 %154 = OpLoad %v4int %intGreen
OpBranch %146 %155 = OpVectorShuffle %v2int %154 %154 0 1
%146 = OpLabel %151 = OpExtInst %v2int %1 SMax %153 %155
%153 = OpPhi %bool %false %134 %152 %145 %156 = OpLoad %v4int %expectedB
OpSelectionMerge %158 None %157 = OpVectorShuffle %v2int %156 %156 0 1
OpBranchConditional %153 %156 %157 %158 = OpIEqual %v2bool %151 %157
%156 = OpLabel %159 = OpAll %bool %158
%159 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1 OpBranch %150
%160 = OpLoad %v4float %159 %150 = OpLabel
OpStore %154 %160 %160 = OpPhi %bool %false %139 %159 %149
OpBranch %158 OpSelectionMerge %162 None
%157 = OpLabel OpBranchConditional %160 %161 %162
%161 = OpAccessChain %_ptr_Uniform_v4float %10 %int_2 %161 = OpLabel
%163 = OpLoad %v4float %161 %164 = OpLoad %v4int %intValues
OpStore %154 %163 %165 = OpVectorShuffle %v3int %164 %164 0 1 2
OpBranch %158 %166 = OpLoad %v4int %intGreen
%158 = OpLabel %167 = OpVectorShuffle %v3int %166 %166 0 1 2
%164 = OpLoad %v4float %154 %163 = OpExtInst %v3int %1 SMax %165 %167
OpReturnValue %164 %168 = OpLoad %v4int %expectedB
%169 = OpVectorShuffle %v3int %168 %168 0 1 2
%170 = OpIEqual %v3bool %163 %169
%171 = OpAll %bool %170
OpBranch %162
%162 = OpLabel
%172 = OpPhi %bool %false %150 %171 %161
OpSelectionMerge %174 None
OpBranchConditional %172 %173 %174
%173 = OpLabel
%176 = OpLoad %v4int %intValues
%177 = OpLoad %v4int %intGreen
%175 = OpExtInst %v4int %1 SMax %176 %177
%178 = OpLoad %v4int %expectedB
%179 = OpIEqual %v4bool %175 %178
%180 = OpAll %bool %179
OpBranch %174
%174 = OpLabel
%181 = OpPhi %bool %false %162 %180 %173
OpSelectionMerge %183 None
OpBranchConditional %181 %182 %183
%182 = OpLabel
%184 = OpLoad %v4int %expectedB
%185 = OpCompositeExtract %int %184 0
%186 = OpIEqual %bool %int_0 %185
OpBranch %183
%183 = OpLabel
%187 = OpPhi %bool %false %174 %186 %182
OpSelectionMerge %189 None
OpBranchConditional %187 %188 %189
%188 = OpLabel
%191 = OpLoad %v4int %expectedB
%192 = OpVectorShuffle %v2int %191 %191 0 1
%193 = OpIEqual %v2bool %190 %192
%194 = OpAll %bool %193
OpBranch %189
%189 = OpLabel
%195 = OpPhi %bool %false %183 %194 %188
OpSelectionMerge %197 None
OpBranchConditional %195 %196 %197
%196 = OpLabel
%199 = OpLoad %v4int %expectedB
%200 = OpVectorShuffle %v3int %199 %199 0 1 2
%201 = OpIEqual %v3bool %198 %200
%202 = OpAll %bool %201
OpBranch %197
%197 = OpLabel
%203 = OpPhi %bool %false %189 %202 %196
OpSelectionMerge %205 None
OpBranchConditional %203 %204 %205
%204 = OpLabel
%206 = OpLoad %v4int %expectedB
%207 = OpIEqual %v4bool %66 %206
%208 = OpAll %bool %207
OpBranch %205
%205 = OpLabel
%209 = OpPhi %bool %false %197 %208 %204
OpSelectionMerge %214 None
OpBranchConditional %209 %212 %213
%212 = OpLabel
%215 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%216 = OpLoad %v4float %215
OpStore %210 %216
OpBranch %214
%213 = OpLabel
%217 = OpAccessChain %_ptr_Uniform_v4float %10 %int_2
%219 = OpLoad %v4float %217
OpStore %210 %219
OpBranch %214
%214 = OpLabel
%220 = OpLoad %v4float %210
OpReturnValue %220
OpFunctionEnd OpFunctionEnd

View File

@ -8,5 +8,5 @@ vec4 main() {
ivec4 intGreen = ivec4(colorGreen * 100.0); ivec4 intGreen = ivec4(colorGreen * 100.0);
ivec4 expectedA = ivec4(50, 50, 75, 225); ivec4 expectedA = ivec4(50, 50, 75, 225);
ivec4 expectedB = ivec4(0, 100, 75, 225); ivec4 expectedB = ivec4(0, 100, 75, 225);
return ((((((max(intValues.x, 50) == expectedA.x && max(intValues.xy, 50) == expectedA.xy) && max(intValues.xyz, 50) == expectedA.xyz) && max(intValues, 50) == expectedA) && max(intValues.x, intGreen.x) == expectedB.x) && max(intValues.xy, intGreen.xy) == expectedB.xy) && max(intValues.xyz, intGreen.xyz) == expectedB.xyz) && max(intValues, intGreen) == expectedB ? colorGreen : colorRed; return ((((((((((((((max(intValues.x, 50) == expectedA.x && max(intValues.xy, 50) == expectedA.xy) && max(intValues.xyz, 50) == expectedA.xyz) && max(intValues, 50) == expectedA) && 50 == expectedA.x) && ivec2(50, 50) == expectedA.xy) && ivec3(50, 50, 75) == expectedA.xyz) && ivec4(50, 50, 75, 225) == expectedA) && max(intValues.x, intGreen.x) == expectedB.x) && max(intValues.xy, intGreen.xy) == expectedB.xy) && max(intValues.xyz, intGreen.xyz) == expectedB.xyz) && max(intValues, intGreen) == expectedB) && 0 == expectedB.x) && ivec2(0, 100) == expectedB.xy) && ivec3(0, 100, 75) == expectedB.xyz) && ivec4(0, 100, 75, 225) == expectedB ? colorGreen : colorRed;
} }

View File

@ -18,6 +18,6 @@ fragment Outputs fragmentMain(Inputs _in [[stage_in]], constant Uniforms& _unifo
int4 intGreen = int4(_uniforms.colorGreen * 100.0); int4 intGreen = int4(_uniforms.colorGreen * 100.0);
int4 expectedA = int4(50, 50, 75, 225); int4 expectedA = int4(50, 50, 75, 225);
int4 expectedB = int4(0, 100, 75, 225); int4 expectedB = int4(0, 100, 75, 225);
_out.sk_FragColor = ((((((max(intValues.x, 50) == expectedA.x && all(max(intValues.xy, 50) == expectedA.xy)) && all(max(intValues.xyz, 50) == expectedA.xyz)) && all(max(intValues, 50) == expectedA)) && max(intValues.x, intGreen.x) == expectedB.x) && all(max(intValues.xy, intGreen.xy) == expectedB.xy)) && all(max(intValues.xyz, intGreen.xyz) == expectedB.xyz)) && all(max(intValues, intGreen) == expectedB) ? _uniforms.colorGreen : _uniforms.colorRed; _out.sk_FragColor = ((((((((((((((max(intValues.x, 50) == expectedA.x && all(max(intValues.xy, 50) == expectedA.xy)) && all(max(intValues.xyz, 50) == expectedA.xyz)) && all(max(intValues, 50) == expectedA)) && 50 == expectedA.x) && all(int2(50, 50) == expectedA.xy)) && all(int3(50, 50, 75) == expectedA.xyz)) && all(int4(50, 50, 75, 225) == expectedA)) && max(intValues.x, intGreen.x) == expectedB.x) && all(max(intValues.xy, intGreen.xy) == expectedB.xy)) && all(max(intValues.xyz, intGreen.xyz) == expectedB.xyz)) && all(max(intValues, intGreen) == expectedB)) && 0 == expectedB.x) && all(int2(0, 100) == expectedB.xy)) && all(int3(0, 100, 75) == expectedB.xyz)) && all(int4(0, 100, 75, 225) == expectedB) ? _uniforms.colorGreen : _uniforms.colorRed;
return _out; return _out;
} }

View File

@ -47,30 +47,47 @@ OpDecorate %67 RelaxedPrecision
OpDecorate %76 RelaxedPrecision OpDecorate %76 RelaxedPrecision
OpDecorate %77 RelaxedPrecision OpDecorate %77 RelaxedPrecision
OpDecorate %78 RelaxedPrecision OpDecorate %78 RelaxedPrecision
OpDecorate %87 RelaxedPrecision OpDecorate %85 RelaxedPrecision
OpDecorate %88 RelaxedPrecision OpDecorate %86 RelaxedPrecision
OpDecorate %91 RelaxedPrecision OpDecorate %91 RelaxedPrecision
OpDecorate %92 RelaxedPrecision OpDecorate %92 RelaxedPrecision
OpDecorate %93 RelaxedPrecision OpDecorate %93 RelaxedPrecision
OpDecorate %94 RelaxedPrecision OpDecorate %99 RelaxedPrecision
OpDecorate %100 RelaxedPrecision
OpDecorate %101 RelaxedPrecision OpDecorate %101 RelaxedPrecision
OpDecorate %102 RelaxedPrecision
OpDecorate %104 RelaxedPrecision
OpDecorate %105 RelaxedPrecision
OpDecorate %106 RelaxedPrecision
OpDecorate %107 RelaxedPrecision OpDecorate %107 RelaxedPrecision
OpDecorate %115 RelaxedPrecision OpDecorate %115 RelaxedPrecision
OpDecorate %116 RelaxedPrecision OpDecorate %116 RelaxedPrecision
OpDecorate %118 RelaxedPrecision
OpDecorate %119 RelaxedPrecision OpDecorate %119 RelaxedPrecision
OpDecorate %120 RelaxedPrecision OpDecorate %120 RelaxedPrecision
OpDecorate %121 RelaxedPrecision OpDecorate %121 RelaxedPrecision
OpDecorate %122 RelaxedPrecision
OpDecorate %129 RelaxedPrecision OpDecorate %129 RelaxedPrecision
OpDecorate %131 RelaxedPrecision OpDecorate %130 RelaxedPrecision
OpDecorate %132 RelaxedPrecision OpDecorate %132 RelaxedPrecision
OpDecorate %141 RelaxedPrecision OpDecorate %133 RelaxedPrecision
OpDecorate %134 RelaxedPrecision
OpDecorate %135 RelaxedPrecision
OpDecorate %143 RelaxedPrecision
OpDecorate %144 RelaxedPrecision OpDecorate %144 RelaxedPrecision
OpDecorate %145 RelaxedPrecision OpDecorate %146 RelaxedPrecision
OpDecorate %147 RelaxedPrecision
OpDecorate %148 RelaxedPrecision
OpDecorate %149 RelaxedPrecision
OpDecorate %157 RelaxedPrecision
OpDecorate %159 RelaxedPrecision
OpDecorate %160 RelaxedPrecision
OpDecorate %166 RelaxedPrecision
OpDecorate %167 RelaxedPrecision
OpDecorate %172 RelaxedPrecision
OpDecorate %173 RelaxedPrecision
OpDecorate %179 RelaxedPrecision
OpDecorate %180 RelaxedPrecision
OpDecorate %181 RelaxedPrecision
OpDecorate %187 RelaxedPrecision
OpDecorate %196 RelaxedPrecision
OpDecorate %199 RelaxedPrecision
OpDecorate %200 RelaxedPrecision
%float = OpTypeFloat 32 %float = OpTypeFloat 32
%v4float = OpTypeVector %float 4 %v4float = OpTypeVector %float 4
%_ptr_Output_v4float = OpTypePointer Output %v4float %_ptr_Output_v4float = OpTypePointer Output %v4float
@ -102,7 +119,10 @@ OpDecorate %145 RelaxedPrecision
%v3float = OpTypeVector %float 3 %v3float = OpTypeVector %float 3
%v3bool = OpTypeVector %bool 3 %v3bool = OpTypeVector %bool 3
%v4bool = OpTypeVector %bool 4 %v4bool = OpTypeVector %bool 4
%91 = OpConstantComposite %v2float %float_n1_25 %float_0
%99 = OpConstantComposite %v3float %float_n1_25 %float_0 %float_0_5
%int_1 = OpConstant %int 1 %int_1 = OpConstant %int 1
%179 = OpConstantComposite %v3float %float_n1_25 %float_0 %float_0
%int_2 = OpConstant %int 2 %int_2 = OpConstant %int 2
%_entrypoint_v = OpFunction %void None %15 %_entrypoint_v = OpFunction %void None %15
%16 = OpLabel %16 = OpLabel
@ -117,7 +137,7 @@ OpFunctionEnd
%25 = OpLabel %25 = OpLabel
%expectedA = OpVariable %_ptr_Function_v4float Function %expectedA = OpVariable %_ptr_Function_v4float Function
%expectedB = OpVariable %_ptr_Function_v4float Function %expectedB = OpVariable %_ptr_Function_v4float Function
%136 = OpVariable %_ptr_Function_v4float Function %191 = OpVariable %_ptr_Function_v4float Function
OpStore %expectedA %30 OpStore %expectedA %30
OpStore %expectedB %33 OpStore %expectedB %33
%36 = OpAccessChain %_ptr_Uniform_v4float %10 %int_0 %36 = OpAccessChain %_ptr_Uniform_v4float %10 %int_0
@ -173,80 +193,156 @@ OpBranch %73
OpSelectionMerge %84 None OpSelectionMerge %84 None
OpBranchConditional %82 %83 %84 OpBranchConditional %82 %83 %84
%83 = OpLabel %83 = OpLabel
%86 = OpAccessChain %_ptr_Uniform_v4float %10 %int_0 %85 = OpLoad %v4float %expectedA
%87 = OpLoad %v4float %86 %86 = OpCompositeExtract %float %85 0
%88 = OpCompositeExtract %float %87 0 %87 = OpFOrdEqual %bool %float_n1_25 %86
%89 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%91 = OpLoad %v4float %89
%92 = OpCompositeExtract %float %91 0
%85 = OpExtInst %float %1 FMin %88 %92
%93 = OpLoad %v4float %expectedB
%94 = OpCompositeExtract %float %93 0
%95 = OpFOrdEqual %bool %85 %94
OpBranch %84 OpBranch %84
%84 = OpLabel %84 = OpLabel
%96 = OpPhi %bool %false %73 %95 %83 %88 = OpPhi %bool %false %73 %87 %83
OpSelectionMerge %90 None
OpBranchConditional %88 %89 %90
%89 = OpLabel
%92 = OpLoad %v4float %expectedA
%93 = OpVectorShuffle %v2float %92 %92 0 1
%94 = OpFOrdEqual %v2bool %91 %93
%95 = OpAll %bool %94
OpBranch %90
%90 = OpLabel
%96 = OpPhi %bool %false %84 %95 %89
OpSelectionMerge %98 None OpSelectionMerge %98 None
OpBranchConditional %96 %97 %98 OpBranchConditional %96 %97 %98
%97 = OpLabel %97 = OpLabel
%100 = OpAccessChain %_ptr_Uniform_v4float %10 %int_0 %100 = OpLoad %v4float %expectedA
%101 = OpLoad %v4float %100 %101 = OpVectorShuffle %v3float %100 %100 0 1 2
%102 = OpVectorShuffle %v2float %101 %101 0 1 %102 = OpFOrdEqual %v3bool %99 %101
%103 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1 %103 = OpAll %bool %102
%104 = OpLoad %v4float %103
%105 = OpVectorShuffle %v2float %104 %104 0 1
%99 = OpExtInst %v2float %1 FMin %102 %105
%106 = OpLoad %v4float %expectedB
%107 = OpVectorShuffle %v2float %106 %106 0 1
%108 = OpFOrdEqual %v2bool %99 %107
%109 = OpAll %bool %108
OpBranch %98 OpBranch %98
%98 = OpLabel %98 = OpLabel
%110 = OpPhi %bool %false %84 %109 %97 %104 = OpPhi %bool %false %90 %103 %97
OpSelectionMerge %106 None
OpBranchConditional %104 %105 %106
%105 = OpLabel
%107 = OpLoad %v4float %expectedA
%108 = OpFOrdEqual %v4bool %30 %107
%109 = OpAll %bool %108
OpBranch %106
%106 = OpLabel
%110 = OpPhi %bool %false %98 %109 %105
OpSelectionMerge %112 None OpSelectionMerge %112 None
OpBranchConditional %110 %111 %112 OpBranchConditional %110 %111 %112
%111 = OpLabel %111 = OpLabel
%114 = OpAccessChain %_ptr_Uniform_v4float %10 %int_0 %114 = OpAccessChain %_ptr_Uniform_v4float %10 %int_0
%115 = OpLoad %v4float %114 %115 = OpLoad %v4float %114
%116 = OpVectorShuffle %v3float %115 %115 0 1 2 %116 = OpCompositeExtract %float %115 0
%117 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1 %117 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%118 = OpLoad %v4float %117 %119 = OpLoad %v4float %117
%119 = OpVectorShuffle %v3float %118 %118 0 1 2 %120 = OpCompositeExtract %float %119 0
%113 = OpExtInst %v3float %1 FMin %116 %119 %113 = OpExtInst %float %1 FMin %116 %120
%120 = OpLoad %v4float %expectedB %121 = OpLoad %v4float %expectedB
%121 = OpVectorShuffle %v3float %120 %120 0 1 2 %122 = OpCompositeExtract %float %121 0
%122 = OpFOrdEqual %v3bool %113 %121 %123 = OpFOrdEqual %bool %113 %122
%123 = OpAll %bool %122
OpBranch %112 OpBranch %112
%112 = OpLabel %112 = OpLabel
%124 = OpPhi %bool %false %98 %123 %111 %124 = OpPhi %bool %false %106 %123 %111
OpSelectionMerge %126 None OpSelectionMerge %126 None
OpBranchConditional %124 %125 %126 OpBranchConditional %124 %125 %126
%125 = OpLabel %125 = OpLabel
%128 = OpAccessChain %_ptr_Uniform_v4float %10 %int_0 %128 = OpAccessChain %_ptr_Uniform_v4float %10 %int_0
%129 = OpLoad %v4float %128 %129 = OpLoad %v4float %128
%130 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1 %130 = OpVectorShuffle %v2float %129 %129 0 1
%131 = OpLoad %v4float %130 %131 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%127 = OpExtInst %v4float %1 FMin %129 %131 %132 = OpLoad %v4float %131
%132 = OpLoad %v4float %expectedB %133 = OpVectorShuffle %v2float %132 %132 0 1
%133 = OpFOrdEqual %v4bool %127 %132 %127 = OpExtInst %v2float %1 FMin %130 %133
%134 = OpAll %bool %133 %134 = OpLoad %v4float %expectedB
%135 = OpVectorShuffle %v2float %134 %134 0 1
%136 = OpFOrdEqual %v2bool %127 %135
%137 = OpAll %bool %136
OpBranch %126 OpBranch %126
%126 = OpLabel %126 = OpLabel
%135 = OpPhi %bool %false %112 %134 %125 %138 = OpPhi %bool %false %112 %137 %125
OpSelectionMerge %139 None OpSelectionMerge %140 None
OpBranchConditional %135 %137 %138 OpBranchConditional %138 %139 %140
%137 = OpLabel
%140 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%141 = OpLoad %v4float %140
OpStore %136 %141
OpBranch %139
%138 = OpLabel
%142 = OpAccessChain %_ptr_Uniform_v4float %10 %int_2
%144 = OpLoad %v4float %142
OpStore %136 %144
OpBranch %139
%139 = OpLabel %139 = OpLabel
%145 = OpLoad %v4float %136 %142 = OpAccessChain %_ptr_Uniform_v4float %10 %int_0
OpReturnValue %145 %143 = OpLoad %v4float %142
%144 = OpVectorShuffle %v3float %143 %143 0 1 2
%145 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%146 = OpLoad %v4float %145
%147 = OpVectorShuffle %v3float %146 %146 0 1 2
%141 = OpExtInst %v3float %1 FMin %144 %147
%148 = OpLoad %v4float %expectedB
%149 = OpVectorShuffle %v3float %148 %148 0 1 2
%150 = OpFOrdEqual %v3bool %141 %149
%151 = OpAll %bool %150
OpBranch %140
%140 = OpLabel
%152 = OpPhi %bool %false %126 %151 %139
OpSelectionMerge %154 None
OpBranchConditional %152 %153 %154
%153 = OpLabel
%156 = OpAccessChain %_ptr_Uniform_v4float %10 %int_0
%157 = OpLoad %v4float %156
%158 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%159 = OpLoad %v4float %158
%155 = OpExtInst %v4float %1 FMin %157 %159
%160 = OpLoad %v4float %expectedB
%161 = OpFOrdEqual %v4bool %155 %160
%162 = OpAll %bool %161
OpBranch %154
%154 = OpLabel
%163 = OpPhi %bool %false %140 %162 %153
OpSelectionMerge %165 None
OpBranchConditional %163 %164 %165
%164 = OpLabel
%166 = OpLoad %v4float %expectedB
%167 = OpCompositeExtract %float %166 0
%168 = OpFOrdEqual %bool %float_n1_25 %167
OpBranch %165
%165 = OpLabel
%169 = OpPhi %bool %false %154 %168 %164
OpSelectionMerge %171 None
OpBranchConditional %169 %170 %171
%170 = OpLabel
%172 = OpLoad %v4float %expectedB
%173 = OpVectorShuffle %v2float %172 %172 0 1
%174 = OpFOrdEqual %v2bool %91 %173
%175 = OpAll %bool %174
OpBranch %171
%171 = OpLabel
%176 = OpPhi %bool %false %165 %175 %170
OpSelectionMerge %178 None
OpBranchConditional %176 %177 %178
%177 = OpLabel
%180 = OpLoad %v4float %expectedB
%181 = OpVectorShuffle %v3float %180 %180 0 1 2
%182 = OpFOrdEqual %v3bool %179 %181
%183 = OpAll %bool %182
OpBranch %178
%178 = OpLabel
%184 = OpPhi %bool %false %171 %183 %177
OpSelectionMerge %186 None
OpBranchConditional %184 %185 %186
%185 = OpLabel
%187 = OpLoad %v4float %expectedB
%188 = OpFOrdEqual %v4bool %33 %187
%189 = OpAll %bool %188
OpBranch %186
%186 = OpLabel
%190 = OpPhi %bool %false %178 %189 %185
OpSelectionMerge %194 None
OpBranchConditional %190 %192 %193
%192 = OpLabel
%195 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%196 = OpLoad %v4float %195
OpStore %191 %196
OpBranch %194
%193 = OpLabel
%197 = OpAccessChain %_ptr_Uniform_v4float %10 %int_2
%199 = OpLoad %v4float %197
OpStore %191 %199
OpBranch %194
%194 = OpLabel
%200 = OpLoad %v4float %191
OpReturnValue %200
OpFunctionEnd OpFunctionEnd

View File

@ -6,5 +6,5 @@ uniform vec4 colorRed;
vec4 main() { vec4 main() {
vec4 expectedA = vec4(-1.25, 0.0, 0.5, 0.5); vec4 expectedA = vec4(-1.25, 0.0, 0.5, 0.5);
vec4 expectedB = vec4(-1.25, 0.0, 0.0, 1.0); vec4 expectedB = vec4(-1.25, 0.0, 0.0, 1.0);
return ((((((min(testInputs.x, 0.5) == expectedA.x && min(testInputs.xy, 0.5) == expectedA.xy) && min(testInputs.xyz, 0.5) == expectedA.xyz) && min(testInputs, 0.5) == expectedA) && min(testInputs.x, colorGreen.x) == expectedB.x) && min(testInputs.xy, colorGreen.xy) == expectedB.xy) && min(testInputs.xyz, colorGreen.xyz) == expectedB.xyz) && min(testInputs, colorGreen) == expectedB ? colorGreen : colorRed; return ((((((((((((((min(testInputs.x, 0.5) == expectedA.x && min(testInputs.xy, 0.5) == expectedA.xy) && min(testInputs.xyz, 0.5) == expectedA.xyz) && min(testInputs, 0.5) == expectedA) && -1.25 == expectedA.x) && vec2(-1.25, 0.0) == expectedA.xy) && vec3(-1.25, 0.0, 0.5) == expectedA.xyz) && vec4(-1.25, 0.0, 0.5, 0.5) == expectedA) && min(testInputs.x, colorGreen.x) == expectedB.x) && min(testInputs.xy, colorGreen.xy) == expectedB.xy) && min(testInputs.xyz, colorGreen.xyz) == expectedB.xyz) && min(testInputs, colorGreen) == expectedB) && -1.25 == expectedB.x) && vec2(-1.25, 0.0) == expectedB.xy) && vec3(-1.25, 0.0, 0.0) == expectedB.xyz) && vec4(-1.25, 0.0, 0.0, 1.0) == expectedB ? colorGreen : colorRed;
} }

View File

@ -16,6 +16,6 @@ fragment Outputs fragmentMain(Inputs _in [[stage_in]], constant Uniforms& _unifo
(void)_out; (void)_out;
float4 expectedA = float4(-1.25, 0.0, 0.5, 0.5); float4 expectedA = float4(-1.25, 0.0, 0.5, 0.5);
float4 expectedB = float4(-1.25, 0.0, 0.0, 1.0); float4 expectedB = float4(-1.25, 0.0, 0.0, 1.0);
_out.sk_FragColor = ((((((min(_uniforms.testInputs.x, 0.5) == expectedA.x && all(min(_uniforms.testInputs.xy, 0.5) == expectedA.xy)) && all(min(_uniforms.testInputs.xyz, 0.5) == expectedA.xyz)) && all(min(_uniforms.testInputs, 0.5) == expectedA)) && min(_uniforms.testInputs.x, _uniforms.colorGreen.x) == expectedB.x) && all(min(_uniforms.testInputs.xy, _uniforms.colorGreen.xy) == expectedB.xy)) && all(min(_uniforms.testInputs.xyz, _uniforms.colorGreen.xyz) == expectedB.xyz)) && all(min(_uniforms.testInputs, _uniforms.colorGreen) == expectedB) ? _uniforms.colorGreen : _uniforms.colorRed; _out.sk_FragColor = ((((((((((((((min(_uniforms.testInputs.x, 0.5) == expectedA.x && all(min(_uniforms.testInputs.xy, 0.5) == expectedA.xy)) && all(min(_uniforms.testInputs.xyz, 0.5) == expectedA.xyz)) && all(min(_uniforms.testInputs, 0.5) == expectedA)) && -1.25 == expectedA.x) && all(float2(-1.25, 0.0) == expectedA.xy)) && all(float3(-1.25, 0.0, 0.5) == expectedA.xyz)) && all(float4(-1.25, 0.0, 0.5, 0.5) == expectedA)) && min(_uniforms.testInputs.x, _uniforms.colorGreen.x) == expectedB.x) && all(min(_uniforms.testInputs.xy, _uniforms.colorGreen.xy) == expectedB.xy)) && all(min(_uniforms.testInputs.xyz, _uniforms.colorGreen.xyz) == expectedB.xyz)) && all(min(_uniforms.testInputs, _uniforms.colorGreen) == expectedB)) && -1.25 == expectedB.x) && all(float2(-1.25, 0.0) == expectedB.xy)) && all(float3(-1.25, 0.0, 0.0) == expectedB.xyz)) && all(float4(-1.25, 0.0, 0.0, 1.0) == expectedB) ? _uniforms.colorGreen : _uniforms.colorRed;
return _out; return _out;
} }

View File

@ -40,9 +40,9 @@ OpDecorate %50 RelaxedPrecision
OpDecorate %52 RelaxedPrecision OpDecorate %52 RelaxedPrecision
OpDecorate %54 RelaxedPrecision OpDecorate %54 RelaxedPrecision
OpDecorate %56 RelaxedPrecision OpDecorate %56 RelaxedPrecision
OpDecorate %159 RelaxedPrecision OpDecorate %214 RelaxedPrecision
OpDecorate %162 RelaxedPrecision OpDecorate %217 RelaxedPrecision
OpDecorate %163 RelaxedPrecision OpDecorate %218 RelaxedPrecision
%float = OpTypeFloat 32 %float = OpTypeFloat 32
%v4float = OpTypeVector %float 4 %v4float = OpTypeVector %float 4
%_ptr_Output_v4float = OpTypePointer Output %v4float %_ptr_Output_v4float = OpTypePointer Output %v4float
@ -78,6 +78,9 @@ OpDecorate %163 RelaxedPrecision
%v3int = OpTypeVector %int 3 %v3int = OpTypeVector %int 3
%v3bool = OpTypeVector %bool 3 %v3bool = OpTypeVector %bool 3
%v4bool = OpTypeVector %bool 4 %v4bool = OpTypeVector %bool 4
%117 = OpConstantComposite %v2int %int_n125 %int_0
%125 = OpConstantComposite %v3int %int_n125 %int_0 %int_50
%196 = OpConstantComposite %v3int %int_n125 %int_0 %int_0
%_ptr_Function_v4float = OpTypePointer Function %v4float %_ptr_Function_v4float = OpTypePointer Function %v4float
%int_2 = OpConstant %int 2 %int_2 = OpConstant %int 2
%_entrypoint_v = OpFunction %void None %15 %_entrypoint_v = OpFunction %void None %15
@ -95,7 +98,7 @@ OpFunctionEnd
%intGreen = OpVariable %_ptr_Function_v4int Function %intGreen = OpVariable %_ptr_Function_v4int Function
%expectedA = OpVariable %_ptr_Function_v4int Function %expectedA = OpVariable %_ptr_Function_v4int Function
%expectedB = OpVariable %_ptr_Function_v4int Function %expectedB = OpVariable %_ptr_Function_v4int Function
%153 = OpVariable %_ptr_Function_v4float Function %208 = OpVariable %_ptr_Function_v4float Function
%30 = OpAccessChain %_ptr_Uniform_v4float %10 %int_0 %30 = OpAccessChain %_ptr_Uniform_v4float %10 %int_0
%33 = OpLoad %v4float %30 %33 = OpLoad %v4float %30
%35 = OpVectorTimesScalar %v4float %33 %float_100 %35 = OpVectorTimesScalar %v4float %33 %float_100
@ -173,72 +176,148 @@ OpBranch %100
OpSelectionMerge %110 None OpSelectionMerge %110 None
OpBranchConditional %108 %109 %110 OpBranchConditional %108 %109 %110
%109 = OpLabel %109 = OpLabel
%112 = OpLoad %v4int %intValues %111 = OpLoad %v4int %expectedA
%113 = OpCompositeExtract %int %112 0 %112 = OpCompositeExtract %int %111 0
%114 = OpLoad %v4int %intGreen %113 = OpIEqual %bool %int_n125 %112
%115 = OpCompositeExtract %int %114 0
%111 = OpExtInst %int %1 SMin %113 %115
%116 = OpLoad %v4int %expectedB
%117 = OpCompositeExtract %int %116 0
%118 = OpIEqual %bool %111 %117
OpBranch %110 OpBranch %110
%110 = OpLabel %110 = OpLabel
%119 = OpPhi %bool %false %100 %118 %109 %114 = OpPhi %bool %false %100 %113 %109
OpSelectionMerge %121 None OpSelectionMerge %116 None
OpBranchConditional %119 %120 %121 OpBranchConditional %114 %115 %116
%120 = OpLabel %115 = OpLabel
%123 = OpLoad %v4int %intValues %118 = OpLoad %v4int %expectedA
%124 = OpVectorShuffle %v2int %123 %123 0 1 %119 = OpVectorShuffle %v2int %118 %118 0 1
%125 = OpLoad %v4int %intGreen %120 = OpIEqual %v2bool %117 %119
%126 = OpVectorShuffle %v2int %125 %125 0 1 %121 = OpAll %bool %120
%122 = OpExtInst %v2int %1 SMin %124 %126 OpBranch %116
%127 = OpLoad %v4int %expectedB %116 = OpLabel
%128 = OpVectorShuffle %v2int %127 %127 0 1 %122 = OpPhi %bool %false %110 %121 %115
%129 = OpIEqual %v2bool %122 %128 OpSelectionMerge %124 None
%130 = OpAll %bool %129 OpBranchConditional %122 %123 %124
OpBranch %121 %123 = OpLabel
%121 = OpLabel %126 = OpLoad %v4int %expectedA
%131 = OpPhi %bool %false %110 %130 %120 %127 = OpVectorShuffle %v3int %126 %126 0 1 2
OpSelectionMerge %133 None %128 = OpIEqual %v3bool %125 %127
OpBranchConditional %131 %132 %133 %129 = OpAll %bool %128
OpBranch %124
%124 = OpLabel
%130 = OpPhi %bool %false %116 %129 %123
OpSelectionMerge %132 None
OpBranchConditional %130 %131 %132
%131 = OpLabel
%133 = OpLoad %v4int %expectedA
%134 = OpIEqual %v4bool %62 %133
%135 = OpAll %bool %134
OpBranch %132
%132 = OpLabel %132 = OpLabel
%135 = OpLoad %v4int %intValues %136 = OpPhi %bool %false %124 %135 %131
%136 = OpVectorShuffle %v3int %135 %135 0 1 2 OpSelectionMerge %138 None
%137 = OpLoad %v4int %intGreen OpBranchConditional %136 %137 %138
%138 = OpVectorShuffle %v3int %137 %137 0 1 2 %137 = OpLabel
%134 = OpExtInst %v3int %1 SMin %136 %138 %140 = OpLoad %v4int %intValues
%139 = OpLoad %v4int %expectedB %141 = OpCompositeExtract %int %140 0
%140 = OpVectorShuffle %v3int %139 %139 0 1 2 %142 = OpLoad %v4int %intGreen
%141 = OpIEqual %v3bool %134 %140 %143 = OpCompositeExtract %int %142 0
%142 = OpAll %bool %141 %139 = OpExtInst %int %1 SMin %141 %143
OpBranch %133 %144 = OpLoad %v4int %expectedB
%133 = OpLabel %145 = OpCompositeExtract %int %144 0
%143 = OpPhi %bool %false %121 %142 %132 %146 = OpIEqual %bool %139 %145
OpSelectionMerge %145 None OpBranch %138
OpBranchConditional %143 %144 %145 %138 = OpLabel
%144 = OpLabel %147 = OpPhi %bool %false %132 %146 %137
%147 = OpLoad %v4int %intValues OpSelectionMerge %149 None
%148 = OpLoad %v4int %intGreen OpBranchConditional %147 %148 %149
%146 = OpExtInst %v4int %1 SMin %147 %148 %148 = OpLabel
%149 = OpLoad %v4int %expectedB %151 = OpLoad %v4int %intValues
%150 = OpIEqual %v4bool %146 %149 %152 = OpVectorShuffle %v2int %151 %151 0 1
%151 = OpAll %bool %150 %153 = OpLoad %v4int %intGreen
OpBranch %145 %154 = OpVectorShuffle %v2int %153 %153 0 1
%145 = OpLabel %150 = OpExtInst %v2int %1 SMin %152 %154
%152 = OpPhi %bool %false %133 %151 %144 %155 = OpLoad %v4int %expectedB
OpSelectionMerge %157 None %156 = OpVectorShuffle %v2int %155 %155 0 1
OpBranchConditional %152 %155 %156 %157 = OpIEqual %v2bool %150 %156
%155 = OpLabel %158 = OpAll %bool %157
%158 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1 OpBranch %149
%159 = OpLoad %v4float %158 %149 = OpLabel
OpStore %153 %159 %159 = OpPhi %bool %false %138 %158 %148
OpBranch %157 OpSelectionMerge %161 None
%156 = OpLabel OpBranchConditional %159 %160 %161
%160 = OpAccessChain %_ptr_Uniform_v4float %10 %int_2 %160 = OpLabel
%162 = OpLoad %v4float %160 %163 = OpLoad %v4int %intValues
OpStore %153 %162 %164 = OpVectorShuffle %v3int %163 %163 0 1 2
OpBranch %157 %165 = OpLoad %v4int %intGreen
%157 = OpLabel %166 = OpVectorShuffle %v3int %165 %165 0 1 2
%163 = OpLoad %v4float %153 %162 = OpExtInst %v3int %1 SMin %164 %166
OpReturnValue %163 %167 = OpLoad %v4int %expectedB
%168 = OpVectorShuffle %v3int %167 %167 0 1 2
%169 = OpIEqual %v3bool %162 %168
%170 = OpAll %bool %169
OpBranch %161
%161 = OpLabel
%171 = OpPhi %bool %false %149 %170 %160
OpSelectionMerge %173 None
OpBranchConditional %171 %172 %173
%172 = OpLabel
%175 = OpLoad %v4int %intValues
%176 = OpLoad %v4int %intGreen
%174 = OpExtInst %v4int %1 SMin %175 %176
%177 = OpLoad %v4int %expectedB
%178 = OpIEqual %v4bool %174 %177
%179 = OpAll %bool %178
OpBranch %173
%173 = OpLabel
%180 = OpPhi %bool %false %161 %179 %172
OpSelectionMerge %182 None
OpBranchConditional %180 %181 %182
%181 = OpLabel
%183 = OpLoad %v4int %expectedB
%184 = OpCompositeExtract %int %183 0
%185 = OpIEqual %bool %int_n125 %184
OpBranch %182
%182 = OpLabel
%186 = OpPhi %bool %false %173 %185 %181
OpSelectionMerge %188 None
OpBranchConditional %186 %187 %188
%187 = OpLabel
%189 = OpLoad %v4int %expectedB
%190 = OpVectorShuffle %v2int %189 %189 0 1
%191 = OpIEqual %v2bool %117 %190
%192 = OpAll %bool %191
OpBranch %188
%188 = OpLabel
%193 = OpPhi %bool %false %182 %192 %187
OpSelectionMerge %195 None
OpBranchConditional %193 %194 %195
%194 = OpLabel
%197 = OpLoad %v4int %expectedB
%198 = OpVectorShuffle %v3int %197 %197 0 1 2
%199 = OpIEqual %v3bool %196 %198
%200 = OpAll %bool %199
OpBranch %195
%195 = OpLabel
%201 = OpPhi %bool %false %188 %200 %194
OpSelectionMerge %203 None
OpBranchConditional %201 %202 %203
%202 = OpLabel
%204 = OpLoad %v4int %expectedB
%205 = OpIEqual %v4bool %65 %204
%206 = OpAll %bool %205
OpBranch %203
%203 = OpLabel
%207 = OpPhi %bool %false %195 %206 %202
OpSelectionMerge %212 None
OpBranchConditional %207 %210 %211
%210 = OpLabel
%213 = OpAccessChain %_ptr_Uniform_v4float %10 %int_1
%214 = OpLoad %v4float %213
OpStore %208 %214
OpBranch %212
%211 = OpLabel
%215 = OpAccessChain %_ptr_Uniform_v4float %10 %int_2
%217 = OpLoad %v4float %215
OpStore %208 %217
OpBranch %212
%212 = OpLabel
%218 = OpLoad %v4float %208
OpReturnValue %218
OpFunctionEnd OpFunctionEnd

View File

@ -8,5 +8,5 @@ vec4 main() {
ivec4 intGreen = ivec4(colorGreen * 100.0); ivec4 intGreen = ivec4(colorGreen * 100.0);
ivec4 expectedA = ivec4(-125, 0, 50, 50); ivec4 expectedA = ivec4(-125, 0, 50, 50);
ivec4 expectedB = ivec4(-125, 0, 0, 100); ivec4 expectedB = ivec4(-125, 0, 0, 100);
return ((((((min(intValues.x, 50) == expectedA.x && min(intValues.xy, 50) == expectedA.xy) && min(intValues.xyz, 50) == expectedA.xyz) && min(intValues, 50) == expectedA) && min(intValues.x, intGreen.x) == expectedB.x) && min(intValues.xy, intGreen.xy) == expectedB.xy) && min(intValues.xyz, intGreen.xyz) == expectedB.xyz) && min(intValues, intGreen) == expectedB ? colorGreen : colorRed; return ((((((((((((((min(intValues.x, 50) == expectedA.x && min(intValues.xy, 50) == expectedA.xy) && min(intValues.xyz, 50) == expectedA.xyz) && min(intValues, 50) == expectedA) && -125 == expectedA.x) && ivec2(-125, 0) == expectedA.xy) && ivec3(-125, 0, 50) == expectedA.xyz) && ivec4(-125, 0, 50, 50) == expectedA) && min(intValues.x, intGreen.x) == expectedB.x) && min(intValues.xy, intGreen.xy) == expectedB.xy) && min(intValues.xyz, intGreen.xyz) == expectedB.xyz) && min(intValues, intGreen) == expectedB) && -125 == expectedB.x) && ivec2(-125, 0) == expectedB.xy) && ivec3(-125, 0, 0) == expectedB.xyz) && ivec4(-125, 0, 0, 100) == expectedB ? colorGreen : colorRed;
} }

View File

@ -18,6 +18,6 @@ fragment Outputs fragmentMain(Inputs _in [[stage_in]], constant Uniforms& _unifo
int4 intGreen = int4(_uniforms.colorGreen * 100.0); int4 intGreen = int4(_uniforms.colorGreen * 100.0);
int4 expectedA = int4(-125, 0, 50, 50); int4 expectedA = int4(-125, 0, 50, 50);
int4 expectedB = int4(-125, 0, 0, 100); int4 expectedB = int4(-125, 0, 0, 100);
_out.sk_FragColor = ((((((min(intValues.x, 50) == expectedA.x && all(min(intValues.xy, 50) == expectedA.xy)) && all(min(intValues.xyz, 50) == expectedA.xyz)) && all(min(intValues, 50) == expectedA)) && min(intValues.x, intGreen.x) == expectedB.x) && all(min(intValues.xy, intGreen.xy) == expectedB.xy)) && all(min(intValues.xyz, intGreen.xyz) == expectedB.xyz)) && all(min(intValues, intGreen) == expectedB) ? _uniforms.colorGreen : _uniforms.colorRed; _out.sk_FragColor = ((((((((((((((min(intValues.x, 50) == expectedA.x && all(min(intValues.xy, 50) == expectedA.xy)) && all(min(intValues.xyz, 50) == expectedA.xyz)) && all(min(intValues, 50) == expectedA)) && -125 == expectedA.x) && all(int2(-125, 0) == expectedA.xy)) && all(int3(-125, 0, 50) == expectedA.xyz)) && all(int4(-125, 0, 50, 50) == expectedA)) && min(intValues.x, intGreen.x) == expectedB.x) && all(min(intValues.xy, intGreen.xy) == expectedB.xy)) && all(min(intValues.xyz, intGreen.xyz) == expectedB.xyz)) && all(min(intValues, intGreen) == expectedB)) && -125 == expectedB.x) && all(int2(-125, 0) == expectedB.xy)) && all(int3(-125, 0, 0) == expectedB.xyz)) && all(int4(-125, 0, 0, 100) == expectedB) ? _uniforms.colorGreen : _uniforms.colorRed;
return _out; return _out;
} }