228 lines · c
1// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --filter "^define |^entry:" --version 22// RUN: %clang_cc1 -triple riscv32 -target-feature +f -target-abi ilp32f -emit-llvm %s -o - \3// RUN: | FileCheck -check-prefixes=CHECK-C,CHECK32-C %s4// RUN: %clang_cc1 -triple riscv32 -target-feature +f -target-feature +d -target-abi ilp32d -emit-llvm %s -o - \5// RUN: | FileCheck -check-prefixes=CHECK-C,CHECK32-C %s6// RUN: %clang_cc1 -triple riscv64 -target-feature +f -target-abi lp64f -emit-llvm %s -o - \7// RUN: | FileCheck -check-prefixes=CHECK-C,CHECK64-C %s8// RUN: %clang_cc1 -triple riscv64 -target-feature +f -target-feature +d -target-abi lp64d -emit-llvm %s -o - \9// RUN: | FileCheck -check-prefixes=CHECK-C,CHECK64-C %s10// RUN: %clang_cc1 -x c++ -triple riscv32 -target-feature +f -target-abi ilp32f -emit-llvm %s -o - \11// RUN: | FileCheck -check-prefixes=CHECK-CXX,CHECK32-CXX %s12// RUN: %clang_cc1 -x c++ -triple riscv32 -target-feature +f -target-feature +d -target-abi ilp32d -emit-llvm %s -o - \13// RUN: | FileCheck -check-prefixes=CHECK-CXX,CHECK32-CXX %s14// RUN: %clang_cc1 -x c++ -triple riscv64 -target-feature +f -target-abi lp64f -emit-llvm %s -o - \15// RUN: | FileCheck -check-prefixes=CHECK-CXX,CHECK64-CXX %s16// RUN: %clang_cc1 -x c++ -triple riscv64 -target-feature +f -target-feature +d -target-abi lp64d -emit-llvm %s -o - \17// RUN: | FileCheck -check-prefixes=CHECK-CXX,CHECK64-CXX %s18 19#include <stdint.h>20 21// Fields containing empty structs or unions are ignored when flattening22// structs for the hard FP ABIs, even in C++. The rules for arrays of empty23// structs or unions are subtle and documented in24// <https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc#hardware-floating-point-calling-convention>.25 26struct empty { struct { struct { } e; }; };27struct s1 { struct empty e; float f; };28 29// CHECK-C-LABEL: define dso_local float @test_s130// CHECK-C-SAME: (float [[TMP0:%.*]]) #[[ATTR0:[0-9]+]] {31// CHECK-C: entry:32//33// CHECK-CXX-LABEL: define dso_local float @_Z7test_s12s134// CHECK-CXX-SAME: (float [[TMP0:%.*]]) #[[ATTR0:[0-9]+]] {35// CHECK-CXX: entry:36//37struct s1 test_s1(struct s1 a) {38 return a;39}40 41struct s2 { struct empty e; int32_t i; float f; };42 43// CHECK-C-LABEL: define dso_local { i32, float } @test_s244// CHECK-C-SAME: (i32 [[TMP0:%.*]], float [[TMP1:%.*]]) #[[ATTR0]] {45// CHECK-C: entry:46//47// CHECK-CXX-LABEL: define dso_local { i32, float } @_Z7test_s22s248// CHECK-CXX-SAME: (i32 [[TMP0:%.*]], float [[TMP1:%.*]]) #[[ATTR0]] {49// CHECK-CXX: entry:50//51struct s2 test_s2(struct s2 a) {52 return a;53}54 55struct s3 { struct empty e; float f; float g; };56 57// CHECK-C-LABEL: define dso_local { float, float } @test_s358// CHECK-C-SAME: (float [[TMP0:%.*]], float [[TMP1:%.*]]) #[[ATTR0]] {59// CHECK-C: entry:60//61// CHECK-CXX-LABEL: define dso_local { float, float } @_Z7test_s32s362// CHECK-CXX-SAME: (float [[TMP0:%.*]], float [[TMP1:%.*]]) #[[ATTR0]] {63// CHECK-CXX: entry:64//65struct s3 test_s3(struct s3 a) {66 return a;67}68 69struct s4 { struct empty e; float __complex__ c; };70 71// CHECK-C-LABEL: define dso_local { float, float } @test_s472// CHECK-C-SAME: (float [[TMP0:%.*]], float [[TMP1:%.*]]) #[[ATTR0]] {73// CHECK-C: entry:74//75// CHECK-CXX-LABEL: define dso_local { float, float } @_Z7test_s42s476// CHECK-CXX-SAME: (float [[TMP0:%.*]], float [[TMP1:%.*]]) #[[ATTR0]] {77// CHECK-CXX: entry:78//79struct s4 test_s4(struct s4 a) {80 return a;81}82 83// An array of empty fields isn't ignored in C++ (this isn't explicit in the84// psABI, but matches observed g++ behaviour).85 86struct s5 { struct empty e[1]; float f; };87 88// CHECK-C-LABEL: define dso_local float @test_s589// CHECK-C-SAME: (float [[TMP0:%.*]]) #[[ATTR0]] {90// CHECK-C: entry:91//92// CHECK32-CXX-LABEL: define dso_local [2 x i32] @_Z7test_s52s593// CHECK32-CXX-SAME: ([2 x i32] [[A_COERCE:%.*]]) #[[ATTR0]] {94// CHECK32-CXX: entry:95//96// CHECK64-CXX-LABEL: define dso_local i64 @_Z7test_s52s597// CHECK64-CXX-SAME: (i64 [[A_COERCE:%.*]]) #[[ATTR0]] {98// CHECK64-CXX: entry:99//100struct s5 test_s5(struct s5 a) {101 return a;102}103 104struct empty_arr { struct { struct { } e[1]; }; };105struct s6 { struct empty_arr e; float f; };106 107// CHECK-C-LABEL: define dso_local float @test_s6108// CHECK-C-SAME: (float [[TMP0:%.*]]) #[[ATTR0]] {109// CHECK-C: entry:110//111// CHECK32-CXX-LABEL: define dso_local [2 x i32] @_Z7test_s62s6112// CHECK32-CXX-SAME: ([2 x i32] [[A_COERCE:%.*]]) #[[ATTR0]] {113// CHECK32-CXX: entry:114//115// CHECK64-CXX-LABEL: define dso_local i64 @_Z7test_s62s6116// CHECK64-CXX-SAME: (i64 [[A_COERCE:%.*]]) #[[ATTR0]] {117// CHECK64-CXX: entry:118//119struct s6 test_s6(struct s6 a) {120 return a;121}122 123struct s7 { struct empty e[0]; float f; };124 125// CHECK-C-LABEL: define dso_local float @test_s7126// CHECK-C-SAME: (float [[TMP0:%.*]]) #[[ATTR0]] {127// CHECK-C: entry:128//129// CHECK-CXX-LABEL: define dso_local float @_Z7test_s72s7130// CHECK-CXX-SAME: (float [[TMP0:%.*]]) #[[ATTR0]] {131// CHECK-CXX: entry:132//133struct s7 test_s7(struct s7 a) {134 return a;135}136 137struct empty_arr0 { struct { struct { } e[0]; }; };138struct s8 { struct empty_arr0 e; float f; };139 140// CHECK-C-LABEL: define dso_local float @test_s8141// CHECK-C-SAME: (float [[TMP0:%.*]]) #[[ATTR0]] {142// CHECK-C: entry:143//144// CHECK-CXX-LABEL: define dso_local float @_Z7test_s82s8145// CHECK-CXX-SAME: (float [[TMP0:%.*]]) #[[ATTR0]] {146// CHECK-CXX: entry:147//148struct s8 test_s8(struct s8 a) {149 return a;150}151 152struct s9 {153 struct empty e;154};155 156// CHECK-C-LABEL: define dso_local void @test_s9157// CHECK-C-SAME: () #[[ATTR0]] {158// CHECK-C: entry:159//160// CHECK32-CXX-LABEL: define dso_local void @_Z7test_s92s9161// CHECK32-CXX-SAME: (i32 [[A_COERCE:%.*]]) #[[ATTR0]] {162// CHECK32-CXX: entry:163//164// CHECK64-CXX-LABEL: define dso_local void @_Z7test_s92s9165// CHECK64-CXX-SAME: (i64 [[A_COERCE:%.*]]) #[[ATTR0]] {166// CHECK64-CXX: entry:167//168void test_s9(struct s9 a) {}169 170struct s10 { };171// CHECK-C-LABEL: define dso_local void @test_s10172// CHECK-C-SAME: () #[[ATTR0]] {173// CHECK-C: entry:174//175// CHECK32-CXX-LABEL: define dso_local i32 @_Z8test_s103s10176// CHECK32-CXX-SAME: (i32 [[A_COERCE:%.*]]) #[[ATTR0]] {177// CHECK32-CXX: entry:178//179// CHECK64-CXX-LABEL: define dso_local i64 @_Z8test_s103s10180// CHECK64-CXX-SAME: (i64 [[A_COERCE:%.*]]) #[[ATTR0]] {181// CHECK64-CXX: entry:182//183struct s10 test_s10(struct s10 a) {184 return a;185}186 187struct s11 { int : 0; };188// CHECK-C-LABEL: define dso_local void @test_s11189// CHECK-C-SAME: () #[[ATTR0]] {190// CHECK-C: entry:191//192// CHECK32-CXX-LABEL: define dso_local i32 @_Z8test_s113s11193// CHECK32-CXX-SAME: (i32 [[A_COERCE:%.*]]) #[[ATTR0]] {194// CHECK32-CXX: entry:195//196// CHECK64-CXX-LABEL: define dso_local i64 @_Z8test_s113s11197// CHECK64-CXX-SAME: (i64 [[A_COERCE:%.*]]) #[[ATTR0]] {198// CHECK64-CXX: entry:199//200struct s11 test_s11(struct s11 a) {201 return a;202}203 204struct s12 {int x[0];};205// CHECK32-C-LABEL: define dso_local i32 @test_s12206// CHECK32-C-SAME: (i32 noundef [[I1:%.*]], i32 noundef [[I2:%.*]]) #[[ATTR0]] {207// CHECK32-C: entry:208//209// CHECK64-C-LABEL: define dso_local signext i32 @test_s12210// CHECK64-C-SAME: (i32 noundef signext [[I1:%.*]], i32 noundef signext [[I2:%.*]]) #[[ATTR0]] {211// CHECK64-C: entry:212//213// CHECK32-CXX-LABEL: define dso_local noundef i32 @_Z8test_s12i3s12i214// CHECK32-CXX-SAME: (i32 noundef [[I1:%.*]], i32 noundef [[I2:%.*]]) #[[ATTR0]] {215// CHECK32-CXX: entry:216//217// CHECK64-CXX-LABEL: define dso_local noundef signext i32 @_Z8test_s12i3s12i218// CHECK64-CXX-SAME: (i32 noundef signext [[I1:%.*]], i32 noundef signext [[I2:%.*]]) #[[ATTR0]] {219// CHECK64-CXX: entry:220//221int test_s12(int32_t i1, struct s12 a, int32_t i2) {222 return i2;223}224 225//// NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:226// CHECK32-C: {{.*}}227// CHECK64-C: {{.*}}228