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 32 static uint32_t __attribute__((noinline)) foo(uint32_t x) { return x * x; } 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 } 75