| Index: crosstest/test_stacksave.c
|
| diff --git a/crosstest/test_stacksave.c b/crosstest/test_stacksave.c
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..b0e9b5e2be9f943c314c511e79d1bfe8dea6b07a
|
| --- /dev/null
|
| +++ b/crosstest/test_stacksave.c
|
| @@ -0,0 +1,76 @@
|
| +//===- subzero/crosstest/test_stacksave.c - Implementation for tests ------===//
|
| +//
|
| +// The Subzero Code Generator
|
| +//
|
| +// This file is distributed under the University of Illinois Open Source
|
| +// License. See LICENSE.TXT for details.
|
| +//
|
| +//===----------------------------------------------------------------------===//
|
| +//
|
| +// This aims to test that C99's VLAs (which use stacksave/stackrestore
|
| +// intrinsics) work fine.
|
| +//
|
| +//===----------------------------------------------------------------------===//
|
| +
|
| +#include <stdint.h>
|
| +
|
| +#include "test_stacksave.h"
|
| +DECLARE_TESTS()
|
| +
|
| +/* NOTE: This has 0 stacksaves, because the vla isn't in a loop,
|
| + * so the vla can just be freed by the epilogue.
|
| + */
|
| +uint32_t test_basic_vla(uint32_t size, uint32_t start, uint32_t inc) {
|
| + uint32_t vla[size];
|
| + uint32_t mid = start + ((size - start) / 2);
|
| + for (uint32_t i = start; i < size; ++i) {
|
| + vla[i] = i + inc;
|
| + }
|
| + return (vla[start] << 2) + (vla[mid] << 1) + vla[size - 1];
|
| +}
|
| +
|
| +static uint32_t __attribute__((noinline)) foo(uint32_t x) {
|
| + return x * x;
|
| +}
|
| +
|
| +/* NOTE: This has 1 stacksave, because the vla is in a loop and should
|
| + * be freed before the next iteration.
|
| + */
|
| +uint32_t test_vla_in_loop(uint32_t size, uint32_t start, uint32_t inc) {
|
| + uint32_t sum = 0;
|
| + for (uint32_t i = start; i < size; ++i) {
|
| + uint32_t size1 = size - i;
|
| + uint32_t vla[size1];
|
| + for (uint32_t j = 0; j < size1; ++j) {
|
| + /* Adjust stack again with a function call. */
|
| + vla[j] = foo(start * j + inc);
|
| + }
|
| + for (uint32_t j = 0; j < size1; ++j) {
|
| + sum += vla[j];
|
| + }
|
| + }
|
| + return sum;
|
| +}
|
| +
|
| +uint32_t test_two_vlas_in_loops(uint32_t size, uint32_t start, uint32_t inc) {
|
| + uint32_t sum = 0;
|
| + for (uint32_t i = start; i < size; ++i) {
|
| + uint32_t size1 = size - i;
|
| + uint32_t vla1[size1];
|
| + for (uint32_t j = 0; j < size1; ++j) {
|
| + uint32_t size2 = size - j;
|
| + uint32_t start2 = 0;
|
| + uint32_t mid2 = size2 / 2;
|
| + uint32_t vla2[size2];
|
| + for (uint32_t k = start2; k < size2; ++k) {
|
| + /* Adjust stack again with a function call. */
|
| + vla2[k] = foo(start * k + inc);
|
| + }
|
| + vla1[j] = (vla2[start2] << 2) + (vla2[mid2] << 1) + vla2[size2 - 1];
|
| + }
|
| + for (uint32_t j = 0; j < size1; ++j) {
|
| + sum += vla1[j];
|
| + }
|
| + }
|
| + return sum;
|
| +}
|
|
|