e11a14d17f
The `break_loop` test causes LLVM to get confused and crash when compiled on some GPUs. The crash goes away if we pass a literal 5 instead of a 5 that is computed at runtime. This also results in a simpler test for SkVM, for better or worse, but we still have coverage for dynamic loop exits in other tests. LLVM crash: https://paste.googleplex.com/4718583155261440 Dangerous shader: https://paste.googleplex.com/4776089520963584 Change-Id: Ic6cbd55a36d2de58e5dd3459d4dfd74acdbc9f91 Bug: skia:13005 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/514538 Reviewed-by: Arman Uguray <armansito@google.com> Commit-Queue: John Stiles <johnstiles@google.com> Auto-Submit: John Stiles <johnstiles@google.com>
116 lines
3.0 KiB
Plaintext
116 lines
3.0 KiB
Plaintext
/*#pragma settings SkVMDebugTrace*/
|
|
|
|
uniform half4 colorRed, colorGreen;
|
|
|
|
// Should return 5
|
|
const int kZero = 0;
|
|
int return_loop(int five) {
|
|
for (int i = kZero; i < 10; ++i) {
|
|
if (i == five) { return i; }
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// Should return 35
|
|
const int kTen = kZero + 10;
|
|
int continue_loop(int five) {
|
|
int sum = 0;
|
|
for (int i = 0; i < kTen; ++i) {
|
|
if (i < five) { continue; }
|
|
sum += i;
|
|
}
|
|
return sum;
|
|
}
|
|
|
|
// Should return 15
|
|
int break_loop(int five) {
|
|
int sum = 0;
|
|
const int kOne = 1;
|
|
for (int i = 0; i < 10; i += kOne) {
|
|
if (i > five) { break; }
|
|
sum += i;
|
|
}
|
|
return sum;
|
|
}
|
|
|
|
bool loop_operator_le() {
|
|
// These loops are inside-out and execute zero times.
|
|
for (int i = 3; i <= 1; ++i) { return false; }
|
|
for (int i = 3; i <= 1; --i) { return false; }
|
|
|
|
int4 result = int4(9);
|
|
for (int i = 1; i <= 3; ++i) {
|
|
result = int4(result.yzw, i);
|
|
}
|
|
return result == int4(9, 1, 2, 3);
|
|
}
|
|
|
|
bool loop_operator_lt() {
|
|
// These loops are inside-out and execute zero times.
|
|
for (int i = 4; i < 1; ++i) { return false; }
|
|
for (int i = 4; i < 1; --i) { return false; }
|
|
|
|
int4 result = int4(9);
|
|
for (int i = 1; i < 4; ++i) {
|
|
result = int4(result.yzw, i);
|
|
}
|
|
return result == int4(9, 1, 2, 3);
|
|
}
|
|
|
|
bool loop_operator_ge() {
|
|
// These loops are inside-out and execute zero times.
|
|
for (int i = 1; i >= 3; ++i) { return false; }
|
|
for (int i = 1; i >= 3; --i) { return false; }
|
|
|
|
int4 result = int4(9);
|
|
for (int i = 3; i >= 1; --i) {
|
|
result = int4(result.yzw, i);
|
|
}
|
|
return result == int4(9, 3, 2, 1);
|
|
}
|
|
|
|
bool loop_operator_gt() {
|
|
// These loops are inside-out and execute zero times.
|
|
for (int i = 0; i > 3; ++i) { return false; }
|
|
for (int i = 0; i > 3; --i) { return false; }
|
|
|
|
int4 result = int4(9);
|
|
for (int i = 3; i > 0; --i) {
|
|
result = int4(result.yzw, i);
|
|
}
|
|
return result == int4(9, 3, 2, 1);
|
|
}
|
|
|
|
bool loop_operator_ne() {
|
|
// This loop executes zero times.
|
|
for (int i = 1; i != 1; ++i) { return false; }
|
|
|
|
int4 result = int4(9);
|
|
for (int i = 1; i != 4; ++i) {
|
|
result = int4(result.yzw, i);
|
|
}
|
|
return result == int4(9, 1, 2, 3);
|
|
}
|
|
|
|
bool loop_operator_eq() {
|
|
// This loop executes zero times.
|
|
for (int i = 1; i == 2; ++i) { return false; }
|
|
|
|
int4 result = int4(9);
|
|
for (int i = 1; i == 1; ++i) {
|
|
result = int4(result.yzw, i);
|
|
}
|
|
return result == int4(9, 9, 9, 1);
|
|
}
|
|
|
|
half4 main(float2 pos) {
|
|
int five = int(clamp(pos.x, colorGreen.g, colorGreen.a)) * 5;
|
|
|
|
// We pass a literal 5 into `break_loop` instead of the variable `five` as a workaround for
|
|
// a Metal crash bug in macOS 12. (skia:13005; Apple FB9937818)
|
|
return (return_loop(five) == 5 && continue_loop(five) == 35 && break_loop(5) == 15 &&
|
|
loop_operator_le() && loop_operator_lt() &&
|
|
loop_operator_ge() && loop_operator_gt() &&
|
|
loop_operator_eq() && loop_operator_ne()) ? colorGreen : colorRed;
|
|
}
|