Jan Voung | 7b34b59 | 2014-07-18 13:12:58 -0700 | [diff] [blame] | 1 | //===- subzero/crosstest/test_stacksave.c - Implementation for tests ------===// |
| 2 | // |
| 3 | // The Subzero Code Generator |
| 4 | // |
| 5 | // This file is distributed under the University of Illinois Open Source |
| 6 | // License. See LICENSE.TXT for details. |
| 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
| 9 | // |
| 10 | // This aims to test that C99's VLAs (which use stacksave/stackrestore |
| 11 | // intrinsics) work fine. |
| 12 | // |
| 13 | //===----------------------------------------------------------------------===// |
| 14 | |
| 15 | #include <stdint.h> |
| 16 | |
| 17 | #include "test_stacksave.h" |
| 18 | DECLARE_TESTS() |
| 19 | |
| 20 | /* NOTE: This has 0 stacksaves, because the vla isn't in a loop, |
| 21 | * so the vla can just be freed by the epilogue. |
| 22 | */ |
| 23 | uint32_t test_basic_vla(uint32_t size, uint32_t start, uint32_t inc) { |
| 24 | uint32_t vla[size]; |
| 25 | uint32_t mid = start + ((size - start) / 2); |
| 26 | for (uint32_t i = start; i < size; ++i) { |
| 27 | vla[i] = i + inc; |
| 28 | } |
| 29 | return (vla[start] << 2) + (vla[mid] << 1) + vla[size - 1]; |
| 30 | } |
| 31 | |
Jim Stichnoth | dd842db | 2015-01-27 12:53:53 -0800 | [diff] [blame] | 32 | static uint32_t __attribute__((noinline)) foo(uint32_t x) { return x * x; } |
Jan Voung | 7b34b59 | 2014-07-18 13:12:58 -0700 | [diff] [blame] | 33 | |
| 34 | /* NOTE: This has 1 stacksave, because the vla is in a loop and should |
| 35 | * be freed before the next iteration. |
| 36 | */ |
| 37 | uint32_t test_vla_in_loop(uint32_t size, uint32_t start, uint32_t inc) { |
| 38 | uint32_t sum = 0; |
| 39 | for (uint32_t i = start; i < size; ++i) { |
| 40 | uint32_t size1 = size - i; |
| 41 | uint32_t vla[size1]; |
| 42 | for (uint32_t j = 0; j < size1; ++j) { |
| 43 | /* Adjust stack again with a function call. */ |
| 44 | vla[j] = foo(start * j + inc); |
| 45 | } |
| 46 | for (uint32_t j = 0; j < size1; ++j) { |
| 47 | sum += vla[j]; |
| 48 | } |
| 49 | } |
| 50 | return sum; |
| 51 | } |
| 52 | |
| 53 | uint32_t test_two_vlas_in_loops(uint32_t size, uint32_t start, uint32_t inc) { |
| 54 | uint32_t sum = 0; |
| 55 | for (uint32_t i = start; i < size; ++i) { |
| 56 | uint32_t size1 = size - i; |
| 57 | uint32_t vla1[size1]; |
| 58 | for (uint32_t j = 0; j < size1; ++j) { |
| 59 | uint32_t size2 = size - j; |
| 60 | uint32_t start2 = 0; |
| 61 | uint32_t mid2 = size2 / 2; |
| 62 | uint32_t vla2[size2]; |
| 63 | for (uint32_t k = start2; k < size2; ++k) { |
| 64 | /* Adjust stack again with a function call. */ |
| 65 | vla2[k] = foo(start * k + inc); |
| 66 | } |
| 67 | vla1[j] = (vla2[start2] << 2) + (vla2[mid2] << 1) + vla2[size2 - 1]; |
| 68 | } |
| 69 | for (uint32_t j = 0; j < size1; ++j) { |
| 70 | sum += vla1[j]; |
| 71 | } |
| 72 | } |
| 73 | return sum; |
| 74 | } |