blob: 176d8fa8187f9a49227dd8bec9dc160238f86168 [file] [log] [blame]
/*
* Copyright (c) 2013 The Native Client Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
/*
* Simple test to verify that C99 VLAs (variable length arrays) work.
*/
#include <stdio.h>
void test_basic_vla(int size) {
/* "volatile", to try to prevent optimizing known summation patterns. */
volatile int vla[size];
for (int i = 0; i < size; ++i) {
vla[i] = i + 10;
}
printf("test_basic_vla w/ size %d\n", size);
printf(" %d + 10 == %d\n", 0, vla[0]);
printf(" %d + 10 == %d\n", size / 2, vla[size / 2]);
printf(" %d + 10 == %d\n", size - 1, vla[size - 1]);
}
void test_basic_in_loop(int size) {
int saved_0 = 0;
int saved_mid = 0;
int saved_last = 0;
for (int i = 0; i < size; ++i) {
volatile int vla[size];
vla[i] = i + 10;
if (i == 0)
saved_0 = vla[i];
if (i == size / 2)
saved_mid = vla[i];
if (i == size - 1)
saved_last = vla[i];
}
printf("test_basic_in_loop w/ size %d\n", size);
printf(" %d + 10 == %d\n", 0, saved_0);
printf(" %d + 10 == %d\n", size / 2, saved_mid);
printf(" %d + 10 == %d\n", size - 1, saved_last);
}
void test_two_in_loops(int size) {
volatile int vla1[size];
for (int i = 0; i < size; i++) {
volatile int vla2[size];
for (int j = 0; j < size; j++) {
vla2[j] = j;
}
/*
* At this point, vla2[size - 1] == size - 1.
* We keep adding that vla2[size - 1] to the previous value in vla1:
* (size - 1) + (size - 1) + ... + (size - 1), a total of "size" times.
*/
if (i > 0)
vla1[i] = vla1[i - 1] + vla2[size - 1];
else
vla1[i] = vla2[size - 1];
}
printf("test_two_in_loops w/ size %d, should be\n (%d - 1) * %d == %d\n",
size, size, size, vla1[size - 1]);
}
/*
* Just like test_two_in_loops, but with recursion.
* Make test_two_recursion_help() "noinline" to ensure that there really
* is a function call within the loop (to adjust the stack), and the
* recursive call doesn't get optimized into a loop.
*/
void test_two_recursion_help(int size,
int counter,
volatile int *arr) __attribute__((noinline));
void test_two_recursion(int size) {
volatile int vla1[size];
for (int i = 0; i < size; i++) {
volatile int vla2[size];
/* Adjust stack again with function call */
test_two_recursion_help(size, 0, vla2);
if (i > 0)
vla1[i] = vla1[i - 1] + vla2[size - 1];
else
vla1[i] = vla2[size - 1];
}
printf("test_two_recursion w/ size %d, should be\n (%d - 1) * %d == %d\n",
size, size, size, vla1[size - 1]);
}
void test_two_recursion_help(int size, int counter, volatile int *arr) {
if (counter < size) {
arr[counter] = counter;
test_two_recursion_help(size, ++counter, arr);
}
}
int main(int argc, char *argv[]) {
volatile int one_iter = 1;
volatile int ten_iters = 10;
test_basic_vla(one_iter);
test_basic_vla(ten_iters);
test_basic_in_loop(one_iter);
test_basic_in_loop(ten_iters);
test_two_in_loops(one_iter);
test_two_in_loops(ten_iters);
test_two_recursion(one_iter);
test_two_recursion(ten_iters);
return 0;
}