brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.2 KiB · 72c23d4 Raw
108 lines · c
1// RUN: %clang_cc1 -triple arm64_32-apple-ios7.0 -target-abi darwinpcs -emit-llvm -o - -O1 -ffreestanding %s | FileCheck %s2 3#include <stdarg.h>4 5typedef struct {6  int a;7} OneInt;8 9// No realignment should be needed here: slot size is 4 bytes.10int test_int(OneInt input, va_list *mylist) {11// CHECK-LABEL: define{{.*}} i32 @test_int(i32 %input12// CHECK: [[START:%.*]] = load ptr, ptr %mylist13// CHECK: [[NEXT:%.*]] = getelementptr inbounds nuw i8, ptr [[START]], i32 414// CHECK: store ptr [[NEXT]], ptr %mylist15 16// CHECK: [[RES:%.*]] = load i32, ptr [[START]]17// CHECK: ret i32 [[RES]]18 19  return va_arg(*mylist, OneInt).a;20}21 22 23typedef struct {24  long long a;25} OneLongLong;26 27// Minimum slot size is 4 bytes, so address needs rounding up to multiple of 8.28long long test_longlong(OneLongLong input, va_list *mylist) {29  // CHECK-LABEL: define{{.*}} i64 @test_longlong(i64 %input30  // CHECK: [[STARTPTR:%.*]] = load ptr, ptr %mylist31  // CHECK: [[ALIGN_TMP:%.+]] = getelementptr inbounds nuw i8, ptr [[STARTPTR]], i32 732  // CHECK: [[ALIGNED_ADDR:%.+]] = tail call align 8 ptr @llvm.ptrmask.p0.i32(ptr nonnull [[ALIGN_TMP]], i32 -8)33  // CHECK: [[NEXT:%.*]] = getelementptr inbounds nuw i8, ptr [[ALIGNED_ADDR]], i32 834  // CHECK: store ptr [[NEXT]], ptr %mylist35 36  // CHECK: [[RES:%.*]] = load i64, ptr [[ALIGNED_ADDR]]37  // CHECK: ret i64 [[RES]]38 39  return va_arg(*mylist, OneLongLong).a;40}41 42 43typedef struct {44  float arr[4];45} HFA;46 47// HFAs take priority over passing large structs indirectly.48float test_hfa(va_list *mylist) {49// CHECK-LABEL: define{{.*}} float @test_hfa50// CHECK: [[START:%.*]] = load ptr, ptr %mylist51 52// CHECK: [[NEXT:%.*]] = getelementptr inbounds nuw i8, ptr [[START]], i32 1653// CHECK: store ptr [[NEXT]], ptr %mylist54 55// CHECK: [[RES:%.*]] = load float, ptr [[START]]56// CHECK: ret float [[RES]]57 58  return va_arg(*mylist, HFA).arr[0];59}60 61// armv7k does not return HFAs normally for variadic functions, so we must match62// that.63HFA test_hfa_return(int n, ...) {64// CHECK-LABEL: define{{.*}} [2 x i64] @test_hfa_return65  HFA h = {0};66  return h;67}68 69typedef struct {70  long long a, b;71  char c;72} BigStruct;73 74// Structs bigger than 16 bytes are passed indirectly: a pointer is placed on75// the stack.76long long test_bigstruct(BigStruct input, va_list *mylist) {77// CHECK-LABEL: define{{.*}} i64 @test_bigstruct(ptr78// CHECK: [[START:%.*]] = load ptr, ptr %mylist79// CHECK: [[NEXT:%.*]] = getelementptr inbounds nuw i8, ptr [[START]], i32 480// CHECK: store ptr [[NEXT]], ptr %mylist81 82// CHECK: [[ADDR:%.*]] = load ptr, ptr [[START]]83// CHECK: [[RES:%.*]] = load i64, ptr [[ADDR]]84// CHECK: ret i64 [[RES]]85 86  return va_arg(*mylist, BigStruct).a;87}88 89typedef struct {90  short arr[3];91} ThreeShorts;92 93// Slot sizes are 4-bytes on arm64_32, so structs with less than 32-bit94// alignment must be passed via "[N x i32]" to be correctly allocated in the95// backend.96short test_threeshorts(ThreeShorts input, va_list *mylist) {97// CHECK-LABEL: define{{.*}} signext i16 @test_threeshorts([2 x i32] %input98 99// CHECK: [[START:%.*]] = load ptr, ptr %mylist100// CHECK: [[NEXT:%.*]] = getelementptr inbounds nuw i8, ptr [[START]], i32 8101// CHECK: store ptr [[NEXT]], ptr %mylist102 103// CHECK: [[RES:%.*]] = load i16, ptr [[START]]104// CHECK: ret i16 [[RES]]105 106  return va_arg(*mylist, ThreeShorts).arr[0];107}108