17b34b59756adbfb4ce623c3252386851c98b0070Jan Voung//===- subzero/crosstest/test_stacksave.c - Implementation for tests ------===// 27b34b59756adbfb4ce623c3252386851c98b0070Jan Voung// 37b34b59756adbfb4ce623c3252386851c98b0070Jan Voung// The Subzero Code Generator 47b34b59756adbfb4ce623c3252386851c98b0070Jan Voung// 57b34b59756adbfb4ce623c3252386851c98b0070Jan Voung// This file is distributed under the University of Illinois Open Source 67b34b59756adbfb4ce623c3252386851c98b0070Jan Voung// License. See LICENSE.TXT for details. 77b34b59756adbfb4ce623c3252386851c98b0070Jan Voung// 87b34b59756adbfb4ce623c3252386851c98b0070Jan Voung//===----------------------------------------------------------------------===// 97b34b59756adbfb4ce623c3252386851c98b0070Jan Voung// 107b34b59756adbfb4ce623c3252386851c98b0070Jan Voung// This aims to test that C99's VLAs (which use stacksave/stackrestore 117b34b59756adbfb4ce623c3252386851c98b0070Jan Voung// intrinsics) work fine. 127b34b59756adbfb4ce623c3252386851c98b0070Jan Voung// 137b34b59756adbfb4ce623c3252386851c98b0070Jan Voung//===----------------------------------------------------------------------===// 147b34b59756adbfb4ce623c3252386851c98b0070Jan Voung 157b34b59756adbfb4ce623c3252386851c98b0070Jan Voung#include <stdint.h> 167b34b59756adbfb4ce623c3252386851c98b0070Jan Voung 177b34b59756adbfb4ce623c3252386851c98b0070Jan Voung#include "test_stacksave.h" 187b34b59756adbfb4ce623c3252386851c98b0070Jan VoungDECLARE_TESTS() 197b34b59756adbfb4ce623c3252386851c98b0070Jan Voung 207b34b59756adbfb4ce623c3252386851c98b0070Jan Voung/* NOTE: This has 0 stacksaves, because the vla isn't in a loop, 217b34b59756adbfb4ce623c3252386851c98b0070Jan Voung * so the vla can just be freed by the epilogue. 227b34b59756adbfb4ce623c3252386851c98b0070Jan Voung */ 237b34b59756adbfb4ce623c3252386851c98b0070Jan Vounguint32_t test_basic_vla(uint32_t size, uint32_t start, uint32_t inc) { 247b34b59756adbfb4ce623c3252386851c98b0070Jan Voung uint32_t vla[size]; 257b34b59756adbfb4ce623c3252386851c98b0070Jan Voung uint32_t mid = start + ((size - start) / 2); 267b34b59756adbfb4ce623c3252386851c98b0070Jan Voung for (uint32_t i = start; i < size; ++i) { 277b34b59756adbfb4ce623c3252386851c98b0070Jan Voung vla[i] = i + inc; 287b34b59756adbfb4ce623c3252386851c98b0070Jan Voung } 297b34b59756adbfb4ce623c3252386851c98b0070Jan Voung return (vla[start] << 2) + (vla[mid] << 1) + vla[size - 1]; 307b34b59756adbfb4ce623c3252386851c98b0070Jan Voung} 317b34b59756adbfb4ce623c3252386851c98b0070Jan Voung 32dd842dbb57b825ed0dd6400648d0602b74c90affJim Stichnothstatic uint32_t __attribute__((noinline)) foo(uint32_t x) { return x * x; } 337b34b59756adbfb4ce623c3252386851c98b0070Jan Voung 347b34b59756adbfb4ce623c3252386851c98b0070Jan Voung/* NOTE: This has 1 stacksave, because the vla is in a loop and should 357b34b59756adbfb4ce623c3252386851c98b0070Jan Voung * be freed before the next iteration. 367b34b59756adbfb4ce623c3252386851c98b0070Jan Voung */ 377b34b59756adbfb4ce623c3252386851c98b0070Jan Vounguint32_t test_vla_in_loop(uint32_t size, uint32_t start, uint32_t inc) { 387b34b59756adbfb4ce623c3252386851c98b0070Jan Voung uint32_t sum = 0; 397b34b59756adbfb4ce623c3252386851c98b0070Jan Voung for (uint32_t i = start; i < size; ++i) { 407b34b59756adbfb4ce623c3252386851c98b0070Jan Voung uint32_t size1 = size - i; 417b34b59756adbfb4ce623c3252386851c98b0070Jan Voung uint32_t vla[size1]; 427b34b59756adbfb4ce623c3252386851c98b0070Jan Voung for (uint32_t j = 0; j < size1; ++j) { 437b34b59756adbfb4ce623c3252386851c98b0070Jan Voung /* Adjust stack again with a function call. */ 447b34b59756adbfb4ce623c3252386851c98b0070Jan Voung vla[j] = foo(start * j + inc); 457b34b59756adbfb4ce623c3252386851c98b0070Jan Voung } 467b34b59756adbfb4ce623c3252386851c98b0070Jan Voung for (uint32_t j = 0; j < size1; ++j) { 477b34b59756adbfb4ce623c3252386851c98b0070Jan Voung sum += vla[j]; 487b34b59756adbfb4ce623c3252386851c98b0070Jan Voung } 497b34b59756adbfb4ce623c3252386851c98b0070Jan Voung } 507b34b59756adbfb4ce623c3252386851c98b0070Jan Voung return sum; 517b34b59756adbfb4ce623c3252386851c98b0070Jan Voung} 527b34b59756adbfb4ce623c3252386851c98b0070Jan Voung 537b34b59756adbfb4ce623c3252386851c98b0070Jan Vounguint32_t test_two_vlas_in_loops(uint32_t size, uint32_t start, uint32_t inc) { 547b34b59756adbfb4ce623c3252386851c98b0070Jan Voung uint32_t sum = 0; 557b34b59756adbfb4ce623c3252386851c98b0070Jan Voung for (uint32_t i = start; i < size; ++i) { 567b34b59756adbfb4ce623c3252386851c98b0070Jan Voung uint32_t size1 = size - i; 577b34b59756adbfb4ce623c3252386851c98b0070Jan Voung uint32_t vla1[size1]; 587b34b59756adbfb4ce623c3252386851c98b0070Jan Voung for (uint32_t j = 0; j < size1; ++j) { 597b34b59756adbfb4ce623c3252386851c98b0070Jan Voung uint32_t size2 = size - j; 607b34b59756adbfb4ce623c3252386851c98b0070Jan Voung uint32_t start2 = 0; 617b34b59756adbfb4ce623c3252386851c98b0070Jan Voung uint32_t mid2 = size2 / 2; 627b34b59756adbfb4ce623c3252386851c98b0070Jan Voung uint32_t vla2[size2]; 637b34b59756adbfb4ce623c3252386851c98b0070Jan Voung for (uint32_t k = start2; k < size2; ++k) { 647b34b59756adbfb4ce623c3252386851c98b0070Jan Voung /* Adjust stack again with a function call. */ 657b34b59756adbfb4ce623c3252386851c98b0070Jan Voung vla2[k] = foo(start * k + inc); 667b34b59756adbfb4ce623c3252386851c98b0070Jan Voung } 677b34b59756adbfb4ce623c3252386851c98b0070Jan Voung vla1[j] = (vla2[start2] << 2) + (vla2[mid2] << 1) + vla2[size2 - 1]; 687b34b59756adbfb4ce623c3252386851c98b0070Jan Voung } 697b34b59756adbfb4ce623c3252386851c98b0070Jan Voung for (uint32_t j = 0; j < size1; ++j) { 707b34b59756adbfb4ce623c3252386851c98b0070Jan Voung sum += vla1[j]; 717b34b59756adbfb4ce623c3252386851c98b0070Jan Voung } 727b34b59756adbfb4ce623c3252386851c98b0070Jan Voung } 737b34b59756adbfb4ce623c3252386851c98b0070Jan Voung return sum; 747b34b59756adbfb4ce623c3252386851c98b0070Jan Voung} 75