xref: /llvm-project/clang/test/CodeGen/RISCV/riscv-abi.cpp (revision 158d72d728261c1e54dc77931372b2322c52849f)
1 // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --filter "^define |^entry:" --version 2
2 // RUN: %clang_cc1 -triple riscv32 -emit-llvm %s -o - \
3 // RUN:   | FileCheck -check-prefixes=ILP32-ILP32F-ILP32D,ILP32-ILP32F,ILP32 %s
4 // RUN: %clang_cc1 -triple riscv32 -target-feature +f -target-abi ilp32f -emit-llvm %s -o - \
5 // RUN:   | FileCheck -check-prefixes=ILP32-ILP32F-ILP32D,ILP32F-ILP32D,ILP32-ILP32F,ILP32F %s
6 // RUN: %clang_cc1 -triple riscv32 -target-feature +f -target-feature +d -target-abi ilp32d -emit-llvm %s -o - \
7 // RUN:   | FileCheck -check-prefixes=ILP32-ILP32F-ILP32D,ILP32F-ILP32D,ILP32D %s
8 
9 // RUN: %clang_cc1 -triple riscv64 -emit-llvm %s -o - \
10 // RUN:   | FileCheck -check-prefixes=LP64-LP64F-LP64D,LP64-LP64F,LP64 %s
11 // RUN: %clang_cc1 -triple riscv64 -target-feature +f -target-abi lp64f -emit-llvm %s -o - \
12 // RUN:   | FileCheck -check-prefixes=LP64-LP64F-LP64D,LP64F-LP64D,LP64-LP64F,LP64F %s
13 // RUN: %clang_cc1 -triple riscv64 -target-feature +f -target-feature +d -target-abi lp64d -emit-llvm %s -o - \
14 // RUN:   | FileCheck -check-prefixes=LP64-LP64F-LP64D,LP64F-LP64D,LP64D %s
15 
16 #include <stdint.h>
17 
18 // Ensure that fields inherited from a parent struct are treated in the same
19 // way as fields directly in the child for the purposes of RISC-V ABI rules.
20 
21 struct parent1_int32_s {
22   int32_t i1;
23 };
24 
25 struct child1_int32_s : parent1_int32_s {
26   int32_t i2;
27 };
28 
29 // ILP32-ILP32F-ILP32D-LABEL: define dso_local [2 x i32] @_Z30int32_int32_struct_inheritance14child1_int32_s
30 // ILP32-ILP32F-ILP32D-SAME: ([2 x i32] [[A_COERCE:%.*]]) #[[ATTR0:[0-9]+]] {
31 // ILP32-ILP32F-ILP32D:  entry:
32 //
33 // LP64-LP64F-LP64D-LABEL: define dso_local i64 @_Z30int32_int32_struct_inheritance14child1_int32_s
34 // LP64-LP64F-LP64D-SAME: (i64 [[A_COERCE:%.*]]) #[[ATTR0:[0-9]+]] {
35 // LP64-LP64F-LP64D:  entry:
36 //
int32_int32_struct_inheritance(struct child1_int32_s a)37 struct child1_int32_s int32_int32_struct_inheritance(struct child1_int32_s a) {
38   return a;
39 }
40 
41 struct parent2_int32_s {
42   int32_t i1;
43 };
44 
45 struct child2_float_s : parent2_int32_s {
46   float f1;
47 };
48 
49 // ILP32-LABEL: define dso_local [2 x i32] @_Z30int32_float_struct_inheritance14child2_float_s
50 // ILP32-SAME: ([2 x i32] [[A_COERCE:%.*]]) #[[ATTR0]] {
51 // ILP32:  entry:
52 //
53 // ILP32F-ILP32D-LABEL: define dso_local { i32, float } @_Z30int32_float_struct_inheritance14child2_float_s
54 // ILP32F-ILP32D-SAME: (i32 [[TMP0:%.*]], float [[TMP1:%.*]]) #[[ATTR0]] {
55 // ILP32F-ILP32D:  entry:
56 //
57 // LP64-LABEL: define dso_local i64 @_Z30int32_float_struct_inheritance14child2_float_s
58 // LP64-SAME: (i64 [[A_COERCE:%.*]]) #[[ATTR0]] {
59 // LP64:  entry:
60 //
61 // LP64F-LP64D-LABEL: define dso_local { i32, float } @_Z30int32_float_struct_inheritance14child2_float_s
62 // LP64F-LP64D-SAME: (i32 [[TMP0:%.*]], float [[TMP1:%.*]]) #[[ATTR0]] {
63 // LP64F-LP64D:  entry:
64 //
int32_float_struct_inheritance(struct child2_float_s a)65 struct child2_float_s int32_float_struct_inheritance(struct child2_float_s a) {
66   return a;
67 }
68 
69 struct parent3_float_s {
70   float f1;
71 };
72 
73 struct child3_int64_s : parent3_float_s {
74   int64_t i1;
75 };
76 
77 // ILP32-ILP32F-ILP32D-LABEL: define dso_local void @_Z30float_int64_struct_inheritance14child3_int64_s
78 // ILP32-ILP32F-ILP32D-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_CHILD3_INT64_S:%.*]]) align 8 [[AGG_RESULT:%.*]], ptr noundef [[A:%.*]]) #[[ATTR0]] {
79 // ILP32-ILP32F-ILP32D:  entry:
80 //
81 // LP64-LABEL: define dso_local [2 x i64] @_Z30float_int64_struct_inheritance14child3_int64_s
82 // LP64-SAME: ([2 x i64] [[A_COERCE:%.*]]) #[[ATTR0]] {
83 // LP64:  entry:
84 //
85 // LP64F-LP64D-LABEL: define dso_local { float, i64 } @_Z30float_int64_struct_inheritance14child3_int64_s
86 // LP64F-LP64D-SAME: (float [[TMP0:%.*]], i64 [[TMP1:%.*]]) #[[ATTR0]] {
87 // LP64F-LP64D:  entry:
88 //
float_int64_struct_inheritance(struct child3_int64_s a)89 struct child3_int64_s float_int64_struct_inheritance(struct child3_int64_s a) {
90   return a;
91 }
92 
93 struct parent4_double_s {
94   double d1;
95 };
96 
97 struct child4_double_s : parent4_double_s {
98   double d1;
99 };
100 
101 // ILP32-ILP32F-LABEL: define dso_local void @_Z32double_double_struct_inheritance15child4_double_s
102 // ILP32-ILP32F-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_CHILD4_DOUBLE_S:%.*]]) align 8 [[AGG_RESULT:%.*]], ptr noundef [[A:%.*]]) #[[ATTR0]] {
103 // ILP32-ILP32F:  entry:
104 //
105 // ILP32D-LABEL: define dso_local { double, double } @_Z32double_double_struct_inheritance15child4_double_s
106 // ILP32D-SAME: (double [[TMP0:%.*]], double [[TMP1:%.*]]) #[[ATTR0]] {
107 // ILP32D:  entry:
108 //
109 // LP64-LP64F-LABEL: define dso_local [2 x i64] @_Z32double_double_struct_inheritance15child4_double_s
110 // LP64-LP64F-SAME: ([2 x i64] [[A_COERCE:%.*]]) #[[ATTR0]] {
111 // LP64-LP64F:  entry:
112 //
113 // LP64D-LABEL: define dso_local { double, double } @_Z32double_double_struct_inheritance15child4_double_s
114 // LP64D-SAME: (double [[TMP0:%.*]], double [[TMP1:%.*]]) #[[ATTR0]] {
115 // LP64D:  entry:
116 //
double_double_struct_inheritance(struct child4_double_s a)117 struct child4_double_s double_double_struct_inheritance(struct child4_double_s a) {
118   return a;
119 }
120 
121 // When virtual inheritance is used, the resulting struct isn't eligible for
122 // passing in registers.
123 
124 struct parent5_virtual_s {
125   int32_t i1;
126 };
127 
128 struct child5_virtual_s : virtual parent5_virtual_s {
129   float f1;
130 };
131 
132 // ILP32-ILP32F-ILP32D-LABEL: define dso_local void @_Z38int32_float_virtual_struct_inheritance16child5_virtual_s
133 // ILP32-ILP32F-ILP32D-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_CHILD5_VIRTUAL_S:%.*]]) align 4 [[AGG_RESULT:%.*]], ptr noundef [[A:%.*]]) #[[ATTR0]] {
134 // ILP32-ILP32F-ILP32D:  entry:
135 //
136 // LP64-LP64F-LP64D-LABEL: define dso_local void @_Z38int32_float_virtual_struct_inheritance16child5_virtual_s
137 // LP64-LP64F-LP64D-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_CHILD5_VIRTUAL_S:%.*]]) align 8 [[AGG_RESULT:%.*]], ptr noundef [[A:%.*]]) #[[ATTR0]] {
138 // LP64-LP64F-LP64D:  entry:
139 //
int32_float_virtual_struct_inheritance(struct child5_virtual_s a)140 struct child5_virtual_s int32_float_virtual_struct_inheritance(struct child5_virtual_s a) {
141   return a;
142 }
143 
144 // Check for correct lowering in the presence of diamond inheritance.
145 
146 struct parent6_float_s {
147   float f1;
148 };
149 
150 struct child6a_s : parent6_float_s {
151 };
152 
153 struct child6b_s : parent6_float_s {
154 };
155 
156 struct grandchild_6_s : child6a_s, child6b_s {
157 };
158 
159 // ILP32F-ILP64D: define{{.*}} { float, float } @_Z38float_float_diamond_struct_inheritance14grandchild_6_s(float %0, float %1)
160 // ILP32-LABEL: define dso_local [2 x i32] @_Z38float_float_diamond_struct_inheritance14grandchild_6_s
161 // ILP32-SAME: ([2 x i32] [[A_COERCE:%.*]]) #[[ATTR0]] {
162 // ILP32:  entry:
163 //
164 // ILP32F-ILP32D-LABEL: define dso_local { float, float } @_Z38float_float_diamond_struct_inheritance14grandchild_6_s
165 // ILP32F-ILP32D-SAME: (float [[TMP0:%.*]], float [[TMP1:%.*]]) #[[ATTR0]] {
166 // ILP32F-ILP32D:  entry:
167 //
168 // LP64-LABEL: define dso_local i64 @_Z38float_float_diamond_struct_inheritance14grandchild_6_s
169 // LP64-SAME: (i64 [[A_COERCE:%.*]]) #[[ATTR0]] {
170 // LP64:  entry:
171 //
172 // LP64F-LP64D-LABEL: define dso_local { float, float } @_Z38float_float_diamond_struct_inheritance14grandchild_6_s
173 // LP64F-LP64D-SAME: (float [[TMP0:%.*]], float [[TMP1:%.*]]) #[[ATTR0]] {
174 // LP64F-LP64D:  entry:
175 //
float_float_diamond_struct_inheritance(struct grandchild_6_s a)176 struct grandchild_6_s float_float_diamond_struct_inheritance(struct grandchild_6_s a) {
177   return a;
178 }
179 
180 // NOTE: These prefixes are unused. Do not add tests below this line:
181 //// NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
182 // ILP32F: {{.*}}
183 // LP64F: {{.*}}
184