Home | History | Annotate | Download | only in crosstest
      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