1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
|
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --filter "^define |^entry:" --version 2
// RUN: %clang_cc1 -triple riscv32 -target-feature +f -target-abi ilp32f -emit-llvm %s -o - \
// RUN: | FileCheck -check-prefixes=CHECK-C,CHECK32-C %s
// RUN: %clang_cc1 -triple riscv32 -target-feature +f -target-feature +d -target-abi ilp32d -emit-llvm %s -o - \
// RUN: | FileCheck -check-prefixes=CHECK-C,CHECK32-C %s
// RUN: %clang_cc1 -triple riscv64 -target-feature +f -target-abi lp64f -emit-llvm %s -o - \
// RUN: | FileCheck -check-prefixes=CHECK-C,CHECK64-C %s
// RUN: %clang_cc1 -triple riscv64 -target-feature +f -target-feature +d -target-abi lp64d -emit-llvm %s -o - \
// RUN: | FileCheck -check-prefixes=CHECK-C,CHECK64-C %s
// RUN: %clang_cc1 -x c++ -triple riscv32 -target-feature +f -target-abi ilp32f -emit-llvm %s -o - \
// RUN: | FileCheck -check-prefixes=CHECK-CXX,CHECK32-CXX %s
// RUN: %clang_cc1 -x c++ -triple riscv32 -target-feature +f -target-feature +d -target-abi ilp32d -emit-llvm %s -o - \
// RUN: | FileCheck -check-prefixes=CHECK-CXX,CHECK32-CXX %s
// RUN: %clang_cc1 -x c++ -triple riscv64 -target-feature +f -target-abi lp64f -emit-llvm %s -o - \
// RUN: | FileCheck -check-prefixes=CHECK-CXX,CHECK64-CXX %s
// RUN: %clang_cc1 -x c++ -triple riscv64 -target-feature +f -target-feature +d -target-abi lp64d -emit-llvm %s -o - \
// RUN: | FileCheck -check-prefixes=CHECK-CXX,CHECK64-CXX %s
#include <stdint.h>
// Fields containing empty structs or unions are ignored when flattening
// structs for the hard FP ABIs, even in C++. The rules for arrays of empty
// structs or unions are subtle and documented in
// <https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc#hardware-floating-point-calling-convention>.
struct empty { struct { struct { } e; }; };
struct s1 { struct empty e; float f; };
// CHECK-C-LABEL: define dso_local float @test_s1
// CHECK-C-SAME: (float [[TMP0:%.*]]) #[[ATTR0:[0-9]+]] {
// CHECK-C: entry:
//
// CHECK-CXX-LABEL: define dso_local float @_Z7test_s12s1
// CHECK-CXX-SAME: (float [[TMP0:%.*]]) #[[ATTR0:[0-9]+]] {
// CHECK-CXX: entry:
//
struct s1 test_s1(struct s1 a) {
return a;
}
struct s2 { struct empty e; int32_t i; float f; };
// CHECK-C-LABEL: define dso_local { i32, float } @test_s2
// CHECK-C-SAME: (i32 [[TMP0:%.*]], float [[TMP1:%.*]]) #[[ATTR0]] {
// CHECK-C: entry:
//
// CHECK-CXX-LABEL: define dso_local { i32, float } @_Z7test_s22s2
// CHECK-CXX-SAME: (i32 [[TMP0:%.*]], float [[TMP1:%.*]]) #[[ATTR0]] {
// CHECK-CXX: entry:
//
struct s2 test_s2(struct s2 a) {
return a;
}
struct s3 { struct empty e; float f; float g; };
// CHECK-C-LABEL: define dso_local { float, float } @test_s3
// CHECK-C-SAME: (float [[TMP0:%.*]], float [[TMP1:%.*]]) #[[ATTR0]] {
// CHECK-C: entry:
//
// CHECK-CXX-LABEL: define dso_local { float, float } @_Z7test_s32s3
// CHECK-CXX-SAME: (float [[TMP0:%.*]], float [[TMP1:%.*]]) #[[ATTR0]] {
// CHECK-CXX: entry:
//
struct s3 test_s3(struct s3 a) {
return a;
}
struct s4 { struct empty e; float __complex__ c; };
// CHECK-C-LABEL: define dso_local { float, float } @test_s4
// CHECK-C-SAME: (float [[TMP0:%.*]], float [[TMP1:%.*]]) #[[ATTR0]] {
// CHECK-C: entry:
//
// CHECK-CXX-LABEL: define dso_local { float, float } @_Z7test_s42s4
// CHECK-CXX-SAME: (float [[TMP0:%.*]], float [[TMP1:%.*]]) #[[ATTR0]] {
// CHECK-CXX: entry:
//
struct s4 test_s4(struct s4 a) {
return a;
}
// An array of empty fields isn't ignored in C++ (this isn't explicit in the
// psABI, but matches observed g++ behaviour).
struct s5 { struct empty e[1]; float f; };
// CHECK-C-LABEL: define dso_local float @test_s5
// CHECK-C-SAME: (float [[TMP0:%.*]]) #[[ATTR0]] {
// CHECK-C: entry:
//
// CHECK32-CXX-LABEL: define dso_local [2 x i32] @_Z7test_s52s5
// CHECK32-CXX-SAME: ([2 x i32] [[A_COERCE:%.*]]) #[[ATTR0]] {
// CHECK32-CXX: entry:
//
// CHECK64-CXX-LABEL: define dso_local i64 @_Z7test_s52s5
// CHECK64-CXX-SAME: (i64 [[A_COERCE:%.*]]) #[[ATTR0]] {
// CHECK64-CXX: entry:
//
struct s5 test_s5(struct s5 a) {
return a;
}
struct empty_arr { struct { struct { } e[1]; }; };
struct s6 { struct empty_arr e; float f; };
// CHECK-C-LABEL: define dso_local float @test_s6
// CHECK-C-SAME: (float [[TMP0:%.*]]) #[[ATTR0]] {
// CHECK-C: entry:
//
// CHECK32-CXX-LABEL: define dso_local [2 x i32] @_Z7test_s62s6
// CHECK32-CXX-SAME: ([2 x i32] [[A_COERCE:%.*]]) #[[ATTR0]] {
// CHECK32-CXX: entry:
//
// CHECK64-CXX-LABEL: define dso_local i64 @_Z7test_s62s6
// CHECK64-CXX-SAME: (i64 [[A_COERCE:%.*]]) #[[ATTR0]] {
// CHECK64-CXX: entry:
//
struct s6 test_s6(struct s6 a) {
return a;
}
struct s7 { struct empty e[0]; float f; };
// CHECK-C-LABEL: define dso_local float @test_s7
// CHECK-C-SAME: (float [[TMP0:%.*]]) #[[ATTR0]] {
// CHECK-C: entry:
//
// CHECK-CXX-LABEL: define dso_local float @_Z7test_s72s7
// CHECK-CXX-SAME: (float [[TMP0:%.*]]) #[[ATTR0]] {
// CHECK-CXX: entry:
//
struct s7 test_s7(struct s7 a) {
return a;
}
struct empty_arr0 { struct { struct { } e[0]; }; };
struct s8 { struct empty_arr0 e; float f; };
// CHECK-C-LABEL: define dso_local float @test_s8
// CHECK-C-SAME: (float [[TMP0:%.*]]) #[[ATTR0]] {
// CHECK-C: entry:
//
// CHECK-CXX-LABEL: define dso_local float @_Z7test_s82s8
// CHECK-CXX-SAME: (float [[TMP0:%.*]]) #[[ATTR0]] {
// CHECK-CXX: entry:
//
struct s8 test_s8(struct s8 a) {
return a;
}
struct s9 {
struct empty e;
};
// CHECK-C-LABEL: define dso_local void @test_s9
// CHECK-C-SAME: () #[[ATTR0]] {
// CHECK-C: entry:
//
// CHECK32-CXX-LABEL: define dso_local void @_Z7test_s92s9
// CHECK32-CXX-SAME: (i32 [[A_COERCE:%.*]]) #[[ATTR0]] {
// CHECK32-CXX: entry:
//
// CHECK64-CXX-LABEL: define dso_local void @_Z7test_s92s9
// CHECK64-CXX-SAME: (i64 [[A_COERCE:%.*]]) #[[ATTR0]] {
// CHECK64-CXX: entry:
//
void test_s9(struct s9 a) {}
//// NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
// CHECK32-C: {{.*}}
// CHECK64-C: {{.*}}
|