brintos

brintos / llvm-project-archived public Read only

0
0
Text · 29.6 KiB · a8a2529 Raw
533 lines · c
1// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 22// RUN: %clang_cc1 -triple loongarch64 -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-LA643// RUN: %clang_cc1 -triple loongarch32 -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-LA324 5struct bfloat1 {6  __bf16 a;7};8 9// CHECK-LABEL: define dso_local bfloat @h110// CHECK-SAME: (bfloat noundef [[A:%.*]]) #[[ATTR0:[0-9]+]] {11// CHECK-NEXT:  entry:12// CHECK-NEXT:    [[RETVAL:%.*]] = alloca [[STRUCT_BFLOAT1:%.*]], align 213// CHECK-NEXT:    [[A_ADDR:%.*]] = alloca bfloat, align 214// CHECK-NEXT:    store bfloat [[A]], ptr [[A_ADDR]], align 215// CHECK-NEXT:    [[TMP0:%.*]] = load bfloat, ptr [[A_ADDR]], align 216// CHECK-NEXT:    [[A1:%.*]] = getelementptr inbounds nuw [[STRUCT_BFLOAT1]], ptr [[RETVAL]], i32 0, i32 017// CHECK-NEXT:    store bfloat [[TMP0]], ptr [[A1]], align 218// CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds nuw { bfloat }, ptr [[RETVAL]], i32 0, i32 019// CHECK-NEXT:    [[TMP2:%.*]] = load bfloat, ptr [[TMP1]], align 220// CHECK-NEXT:    ret bfloat [[TMP2]]21//22struct bfloat1 h1(__bf16 a) {23  struct bfloat1 x;24  x.a = a;25  return x;26}27 28struct bfloat2 {29  __bf16 a;30  __bf16 b;31};32 33// CHECK-LABEL: define dso_local { bfloat, bfloat } @h234// CHECK-SAME: (bfloat noundef [[A:%.*]], bfloat noundef [[B:%.*]]) #[[ATTR0]] {35// CHECK-NEXT:  entry:36// CHECK-NEXT:    [[RETVAL:%.*]] = alloca [[STRUCT_BFLOAT2:%.*]], align 237// CHECK-NEXT:    [[A_ADDR:%.*]] = alloca bfloat, align 238// CHECK-NEXT:    [[B_ADDR:%.*]] = alloca bfloat, align 239// CHECK-NEXT:    store bfloat [[A]], ptr [[A_ADDR]], align 240// CHECK-NEXT:    store bfloat [[B]], ptr [[B_ADDR]], align 241// CHECK-NEXT:    [[TMP0:%.*]] = load bfloat, ptr [[A_ADDR]], align 242// CHECK-NEXT:    [[A1:%.*]] = getelementptr inbounds nuw [[STRUCT_BFLOAT2]], ptr [[RETVAL]], i32 0, i32 043// CHECK-NEXT:    store bfloat [[TMP0]], ptr [[A1]], align 244// CHECK-NEXT:    [[TMP1:%.*]] = load bfloat, ptr [[B_ADDR]], align 245// CHECK-NEXT:    [[B2:%.*]] = getelementptr inbounds nuw [[STRUCT_BFLOAT2]], ptr [[RETVAL]], i32 0, i32 146// CHECK-NEXT:    store bfloat [[TMP1]], ptr [[B2]], align 247// CHECK-NEXT:    [[TMP2:%.*]] = getelementptr inbounds nuw { bfloat, bfloat }, ptr [[RETVAL]], i32 0, i32 048// CHECK-NEXT:    [[TMP3:%.*]] = load bfloat, ptr [[TMP2]], align 249// CHECK-NEXT:    [[TMP4:%.*]] = getelementptr inbounds nuw { bfloat, bfloat }, ptr [[RETVAL]], i32 0, i32 150// CHECK-NEXT:    [[TMP5:%.*]] = load bfloat, ptr [[TMP4]], align 251// CHECK-NEXT:    [[TMP6:%.*]] = insertvalue { bfloat, bfloat } poison, bfloat [[TMP3]], 052// CHECK-NEXT:    [[TMP7:%.*]] = insertvalue { bfloat, bfloat } [[TMP6]], bfloat [[TMP5]], 153// CHECK-NEXT:    ret { bfloat, bfloat } [[TMP7]]54//55struct bfloat2 h2(__bf16 a, __bf16 b) {56  struct bfloat2 x;57  x.a = a;58  x.b = b;59  return x;60}61 62struct bfloat3 {63  __bf16 a;64  __bf16 b;65  __bf16 c;66};67 68// CHECK-LA64-LABEL: define dso_local i64 @h369// CHECK-LA64-SAME: (bfloat noundef [[A:%.*]], bfloat noundef [[B:%.*]], bfloat noundef [[C:%.*]]) #[[ATTR0]] {70// CHECK-LA64-NEXT:  entry:71// CHECK-LA64-NEXT:    [[RETVAL:%.*]] = alloca [[STRUCT_BFLOAT3:%.*]], align 272// CHECK-LA64-NEXT:    [[A_ADDR:%.*]] = alloca bfloat, align 273// CHECK-LA64-NEXT:    [[B_ADDR:%.*]] = alloca bfloat, align 274// CHECK-LA64-NEXT:    [[C_ADDR:%.*]] = alloca bfloat, align 275// CHECK-LA64-NEXT:    [[RETVAL_COERCE:%.*]] = alloca i64, align 876// CHECK-LA64-NEXT:    store bfloat [[A]], ptr [[A_ADDR]], align 277// CHECK-LA64-NEXT:    store bfloat [[B]], ptr [[B_ADDR]], align 278// CHECK-LA64-NEXT:    store bfloat [[C]], ptr [[C_ADDR]], align 279// CHECK-LA64-NEXT:    [[TMP0:%.*]] = load bfloat, ptr [[A_ADDR]], align 280// CHECK-LA64-NEXT:    [[A1:%.*]] = getelementptr inbounds nuw [[STRUCT_BFLOAT3]], ptr [[RETVAL]], i32 0, i32 081// CHECK-LA64-NEXT:    store bfloat [[TMP0]], ptr [[A1]], align 282// CHECK-LA64-NEXT:    [[TMP1:%.*]] = load bfloat, ptr [[B_ADDR]], align 283// CHECK-LA64-NEXT:    [[B2:%.*]] = getelementptr inbounds nuw [[STRUCT_BFLOAT3]], ptr [[RETVAL]], i32 0, i32 184// CHECK-LA64-NEXT:    store bfloat [[TMP1]], ptr [[B2]], align 285// CHECK-LA64-NEXT:    [[TMP2:%.*]] = load bfloat, ptr [[C_ADDR]], align 286// CHECK-LA64-NEXT:    [[C3:%.*]] = getelementptr inbounds nuw [[STRUCT_BFLOAT3]], ptr [[RETVAL]], i32 0, i32 287// CHECK-LA64-NEXT:    store bfloat [[TMP2]], ptr [[C3]], align 288// CHECK-LA64-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[RETVAL_COERCE]], ptr align 2 [[RETVAL]], i64 6, i1 false)89// CHECK-LA64-NEXT:    [[TMP3:%.*]] = load i64, ptr [[RETVAL_COERCE]], align 890// CHECK-LA64-NEXT:    ret i64 [[TMP3]]91//92// CHECK-LA32-LABEL: define dso_local [2 x i32] @h393// CHECK-LA32-SAME: (bfloat noundef [[A:%.*]], bfloat noundef [[B:%.*]], bfloat noundef [[C:%.*]]) #[[ATTR0]] {94// CHECK-LA32-NEXT:  entry:95// CHECK-LA32-NEXT:    [[RETVAL:%.*]] = alloca [[STRUCT_BFLOAT3:%.*]], align 296// CHECK-LA32-NEXT:    [[A_ADDR:%.*]] = alloca bfloat, align 297// CHECK-LA32-NEXT:    [[B_ADDR:%.*]] = alloca bfloat, align 298// CHECK-LA32-NEXT:    [[C_ADDR:%.*]] = alloca bfloat, align 299// CHECK-LA32-NEXT:    [[RETVAL_COERCE:%.*]] = alloca [2 x i32], align 4100// CHECK-LA32-NEXT:    store bfloat [[A]], ptr [[A_ADDR]], align 2101// CHECK-LA32-NEXT:    store bfloat [[B]], ptr [[B_ADDR]], align 2102// CHECK-LA32-NEXT:    store bfloat [[C]], ptr [[C_ADDR]], align 2103// CHECK-LA32-NEXT:    [[TMP0:%.*]] = load bfloat, ptr [[A_ADDR]], align 2104// CHECK-LA32-NEXT:    [[A1:%.*]] = getelementptr inbounds nuw [[STRUCT_BFLOAT3]], ptr [[RETVAL]], i32 0, i32 0105// CHECK-LA32-NEXT:    store bfloat [[TMP0]], ptr [[A1]], align 2106// CHECK-LA32-NEXT:    [[TMP1:%.*]] = load bfloat, ptr [[B_ADDR]], align 2107// CHECK-LA32-NEXT:    [[B2:%.*]] = getelementptr inbounds nuw [[STRUCT_BFLOAT3]], ptr [[RETVAL]], i32 0, i32 1108// CHECK-LA32-NEXT:    store bfloat [[TMP1]], ptr [[B2]], align 2109// CHECK-LA32-NEXT:    [[TMP2:%.*]] = load bfloat, ptr [[C_ADDR]], align 2110// CHECK-LA32-NEXT:    [[C3:%.*]] = getelementptr inbounds nuw [[STRUCT_BFLOAT3]], ptr [[RETVAL]], i32 0, i32 2111// CHECK-LA32-NEXT:    store bfloat [[TMP2]], ptr [[C3]], align 2112// CHECK-LA32-NEXT:    call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[RETVAL_COERCE]], ptr align 2 [[RETVAL]], i32 6, i1 false)113// CHECK-LA32-NEXT:    [[TMP3:%.*]] = load [2 x i32], ptr [[RETVAL_COERCE]], align 4114// CHECK-LA32-NEXT:    ret [2 x i32] [[TMP3]]115//116struct bfloat3 h3(__bf16 a, __bf16 b, __bf16 c) {117  struct bfloat3 x;118  x.a = a;119  x.b = b;120  x.c = c;121  return x;122}123 124struct bfloat4 {125  __bf16 a;126  __bf16 b;127  __bf16 c;128  __bf16 d;129};130 131// CHECK-LA64-LABEL: define dso_local i64 @h4132// CHECK-LA64-SAME: (bfloat noundef [[A:%.*]], bfloat noundef [[B:%.*]], bfloat noundef [[C:%.*]], bfloat noundef [[D:%.*]]) #[[ATTR0]] {133// CHECK-LA64-NEXT:  entry:134// CHECK-LA64-NEXT:    [[RETVAL:%.*]] = alloca [[STRUCT_BFLOAT4:%.*]], align 2135// CHECK-LA64-NEXT:    [[A_ADDR:%.*]] = alloca bfloat, align 2136// CHECK-LA64-NEXT:    [[B_ADDR:%.*]] = alloca bfloat, align 2137// CHECK-LA64-NEXT:    [[C_ADDR:%.*]] = alloca bfloat, align 2138// CHECK-LA64-NEXT:    [[D_ADDR:%.*]] = alloca bfloat, align 2139// CHECK-LA64-NEXT:    store bfloat [[A]], ptr [[A_ADDR]], align 2140// CHECK-LA64-NEXT:    store bfloat [[B]], ptr [[B_ADDR]], align 2141// CHECK-LA64-NEXT:    store bfloat [[C]], ptr [[C_ADDR]], align 2142// CHECK-LA64-NEXT:    store bfloat [[D]], ptr [[D_ADDR]], align 2143// CHECK-LA64-NEXT:    [[TMP0:%.*]] = load bfloat, ptr [[A_ADDR]], align 2144// CHECK-LA64-NEXT:    [[A1:%.*]] = getelementptr inbounds nuw [[STRUCT_BFLOAT4]], ptr [[RETVAL]], i32 0, i32 0145// CHECK-LA64-NEXT:    store bfloat [[TMP0]], ptr [[A1]], align 2146// CHECK-LA64-NEXT:    [[TMP1:%.*]] = load bfloat, ptr [[B_ADDR]], align 2147// CHECK-LA64-NEXT:    [[B2:%.*]] = getelementptr inbounds nuw [[STRUCT_BFLOAT4]], ptr [[RETVAL]], i32 0, i32 1148// CHECK-LA64-NEXT:    store bfloat [[TMP1]], ptr [[B2]], align 2149// CHECK-LA64-NEXT:    [[TMP2:%.*]] = load bfloat, ptr [[C_ADDR]], align 2150// CHECK-LA64-NEXT:    [[C3:%.*]] = getelementptr inbounds nuw [[STRUCT_BFLOAT4]], ptr [[RETVAL]], i32 0, i32 2151// CHECK-LA64-NEXT:    store bfloat [[TMP2]], ptr [[C3]], align 2152// CHECK-LA64-NEXT:    [[TMP3:%.*]] = load bfloat, ptr [[D_ADDR]], align 2153// CHECK-LA64-NEXT:    [[D4:%.*]] = getelementptr inbounds nuw [[STRUCT_BFLOAT4]], ptr [[RETVAL]], i32 0, i32 3154// CHECK-LA64-NEXT:    store bfloat [[TMP3]], ptr [[D4]], align 2155// CHECK-LA64-NEXT:    [[TMP4:%.*]] = load i64, ptr [[RETVAL]], align 2156// CHECK-LA64-NEXT:    ret i64 [[TMP4]]157//158// CHECK-LA32-LABEL: define dso_local [2 x i32] @h4159// CHECK-LA32-SAME: (bfloat noundef [[A:%.*]], bfloat noundef [[B:%.*]], bfloat noundef [[C:%.*]], bfloat noundef [[D:%.*]]) #[[ATTR0]] {160// CHECK-LA32-NEXT:  entry:161// CHECK-LA32-NEXT:    [[RETVAL:%.*]] = alloca [[STRUCT_BFLOAT4:%.*]], align 2162// CHECK-LA32-NEXT:    [[A_ADDR:%.*]] = alloca bfloat, align 2163// CHECK-LA32-NEXT:    [[B_ADDR:%.*]] = alloca bfloat, align 2164// CHECK-LA32-NEXT:    [[C_ADDR:%.*]] = alloca bfloat, align 2165// CHECK-LA32-NEXT:    [[D_ADDR:%.*]] = alloca bfloat, align 2166// CHECK-LA32-NEXT:    store bfloat [[A]], ptr [[A_ADDR]], align 2167// CHECK-LA32-NEXT:    store bfloat [[B]], ptr [[B_ADDR]], align 2168// CHECK-LA32-NEXT:    store bfloat [[C]], ptr [[C_ADDR]], align 2169// CHECK-LA32-NEXT:    store bfloat [[D]], ptr [[D_ADDR]], align 2170// CHECK-LA32-NEXT:    [[TMP0:%.*]] = load bfloat, ptr [[A_ADDR]], align 2171// CHECK-LA32-NEXT:    [[A1:%.*]] = getelementptr inbounds nuw [[STRUCT_BFLOAT4]], ptr [[RETVAL]], i32 0, i32 0172// CHECK-LA32-NEXT:    store bfloat [[TMP0]], ptr [[A1]], align 2173// CHECK-LA32-NEXT:    [[TMP1:%.*]] = load bfloat, ptr [[B_ADDR]], align 2174// CHECK-LA32-NEXT:    [[B2:%.*]] = getelementptr inbounds nuw [[STRUCT_BFLOAT4]], ptr [[RETVAL]], i32 0, i32 1175// CHECK-LA32-NEXT:    store bfloat [[TMP1]], ptr [[B2]], align 2176// CHECK-LA32-NEXT:    [[TMP2:%.*]] = load bfloat, ptr [[C_ADDR]], align 2177// CHECK-LA32-NEXT:    [[C3:%.*]] = getelementptr inbounds nuw [[STRUCT_BFLOAT4]], ptr [[RETVAL]], i32 0, i32 2178// CHECK-LA32-NEXT:    store bfloat [[TMP2]], ptr [[C3]], align 2179// CHECK-LA32-NEXT:    [[TMP3:%.*]] = load bfloat, ptr [[D_ADDR]], align 2180// CHECK-LA32-NEXT:    [[D4:%.*]] = getelementptr inbounds nuw [[STRUCT_BFLOAT4]], ptr [[RETVAL]], i32 0, i32 3181// CHECK-LA32-NEXT:    store bfloat [[TMP3]], ptr [[D4]], align 2182// CHECK-LA32-NEXT:    [[TMP4:%.*]] = load [2 x i32], ptr [[RETVAL]], align 2183// CHECK-LA32-NEXT:    ret [2 x i32] [[TMP4]]184//185struct bfloat4 h4(__bf16 a, __bf16 b, __bf16 c, __bf16 d) {186  struct bfloat4 x;187  x.a = a;188  x.b = b;189  x.c = c;190  x.d = d;191  return x;192}193 194struct floatbfloat {195  float a;196  __bf16 b;197};198 199// CHECK-LABEL: define dso_local { float, bfloat } @fh200// CHECK-SAME: (float noundef [[A:%.*]], bfloat noundef [[B:%.*]]) #[[ATTR0]] {201// CHECK-NEXT:  entry:202// CHECK-NEXT:    [[RETVAL:%.*]] = alloca [[STRUCT_FLOATBFLOAT:%.*]], align 4203// CHECK-NEXT:    [[A_ADDR:%.*]] = alloca float, align 4204// CHECK-NEXT:    [[B_ADDR:%.*]] = alloca bfloat, align 2205// CHECK-NEXT:    store float [[A]], ptr [[A_ADDR]], align 4206// CHECK-NEXT:    store bfloat [[B]], ptr [[B_ADDR]], align 2207// CHECK-NEXT:    [[TMP0:%.*]] = load float, ptr [[A_ADDR]], align 4208// CHECK-NEXT:    [[A1:%.*]] = getelementptr inbounds nuw [[STRUCT_FLOATBFLOAT]], ptr [[RETVAL]], i32 0, i32 0209// CHECK-NEXT:    store float [[TMP0]], ptr [[A1]], align 4210// CHECK-NEXT:    [[TMP1:%.*]] = load bfloat, ptr [[B_ADDR]], align 2211// CHECK-NEXT:    [[B2:%.*]] = getelementptr inbounds nuw [[STRUCT_FLOATBFLOAT]], ptr [[RETVAL]], i32 0, i32 1212// CHECK-NEXT:    store bfloat [[TMP1]], ptr [[B2]], align 4213// CHECK-NEXT:    [[TMP2:%.*]] = getelementptr inbounds nuw { float, bfloat }, ptr [[RETVAL]], i32 0, i32 0214// CHECK-NEXT:    [[TMP3:%.*]] = load float, ptr [[TMP2]], align 4215// CHECK-NEXT:    [[TMP4:%.*]] = getelementptr inbounds nuw { float, bfloat }, ptr [[RETVAL]], i32 0, i32 1216// CHECK-NEXT:    [[TMP5:%.*]] = load bfloat, ptr [[TMP4]], align 4217// CHECK-NEXT:    [[TMP6:%.*]] = insertvalue { float, bfloat } poison, float [[TMP3]], 0218// CHECK-NEXT:    [[TMP7:%.*]] = insertvalue { float, bfloat } [[TMP6]], bfloat [[TMP5]], 1219// CHECK-NEXT:    ret { float, bfloat } [[TMP7]]220//221struct floatbfloat fh(float a, __bf16 b) {222  struct floatbfloat x;223  x.a = a;224  x.b = b;225  return x;226}227 228struct floatbfloat2 {229  float a;230  __bf16 b;231  __bf16 c;232};233 234// CHECK-LA64-LABEL: define dso_local i64 @fh2235// CHECK-LA64-SAME: (float noundef [[A:%.*]], bfloat noundef [[B:%.*]], bfloat noundef [[C:%.*]]) #[[ATTR0]] {236// CHECK-LA64-NEXT:  entry:237// CHECK-LA64-NEXT:    [[RETVAL:%.*]] = alloca [[STRUCT_FLOATBFLOAT2:%.*]], align 4238// CHECK-LA64-NEXT:    [[A_ADDR:%.*]] = alloca float, align 4239// CHECK-LA64-NEXT:    [[B_ADDR:%.*]] = alloca bfloat, align 2240// CHECK-LA64-NEXT:    [[C_ADDR:%.*]] = alloca bfloat, align 2241// CHECK-LA64-NEXT:    store float [[A]], ptr [[A_ADDR]], align 4242// CHECK-LA64-NEXT:    store bfloat [[B]], ptr [[B_ADDR]], align 2243// CHECK-LA64-NEXT:    store bfloat [[C]], ptr [[C_ADDR]], align 2244// CHECK-LA64-NEXT:    [[TMP0:%.*]] = load float, ptr [[A_ADDR]], align 4245// CHECK-LA64-NEXT:    [[A1:%.*]] = getelementptr inbounds nuw [[STRUCT_FLOATBFLOAT2]], ptr [[RETVAL]], i32 0, i32 0246// CHECK-LA64-NEXT:    store float [[TMP0]], ptr [[A1]], align 4247// CHECK-LA64-NEXT:    [[TMP1:%.*]] = load bfloat, ptr [[B_ADDR]], align 2248// CHECK-LA64-NEXT:    [[B2:%.*]] = getelementptr inbounds nuw [[STRUCT_FLOATBFLOAT2]], ptr [[RETVAL]], i32 0, i32 1249// CHECK-LA64-NEXT:    store bfloat [[TMP1]], ptr [[B2]], align 4250// CHECK-LA64-NEXT:    [[TMP2:%.*]] = load bfloat, ptr [[C_ADDR]], align 2251// CHECK-LA64-NEXT:    [[C3:%.*]] = getelementptr inbounds nuw [[STRUCT_FLOATBFLOAT2]], ptr [[RETVAL]], i32 0, i32 2252// CHECK-LA64-NEXT:    store bfloat [[TMP2]], ptr [[C3]], align 2253// CHECK-LA64-NEXT:    [[TMP3:%.*]] = load i64, ptr [[RETVAL]], align 4254// CHECK-LA64-NEXT:    ret i64 [[TMP3]]255//256// CHECK-LA32-LABEL: define dso_local [2 x i32] @fh2257// CHECK-LA32-SAME: (float noundef [[A:%.*]], bfloat noundef [[B:%.*]], bfloat noundef [[C:%.*]]) #[[ATTR0]] {258// CHECK-LA32-NEXT:  entry:259// CHECK-LA32-NEXT:    [[RETVAL:%.*]] = alloca [[STRUCT_FLOATBFLOAT2:%.*]], align 4260// CHECK-LA32-NEXT:    [[A_ADDR:%.*]] = alloca float, align 4261// CHECK-LA32-NEXT:    [[B_ADDR:%.*]] = alloca bfloat, align 2262// CHECK-LA32-NEXT:    [[C_ADDR:%.*]] = alloca bfloat, align 2263// CHECK-LA32-NEXT:    store float [[A]], ptr [[A_ADDR]], align 4264// CHECK-LA32-NEXT:    store bfloat [[B]], ptr [[B_ADDR]], align 2265// CHECK-LA32-NEXT:    store bfloat [[C]], ptr [[C_ADDR]], align 2266// CHECK-LA32-NEXT:    [[TMP0:%.*]] = load float, ptr [[A_ADDR]], align 4267// CHECK-LA32-NEXT:    [[A1:%.*]] = getelementptr inbounds nuw [[STRUCT_FLOATBFLOAT2]], ptr [[RETVAL]], i32 0, i32 0268// CHECK-LA32-NEXT:    store float [[TMP0]], ptr [[A1]], align 4269// CHECK-LA32-NEXT:    [[TMP1:%.*]] = load bfloat, ptr [[B_ADDR]], align 2270// CHECK-LA32-NEXT:    [[B2:%.*]] = getelementptr inbounds nuw [[STRUCT_FLOATBFLOAT2]], ptr [[RETVAL]], i32 0, i32 1271// CHECK-LA32-NEXT:    store bfloat [[TMP1]], ptr [[B2]], align 4272// CHECK-LA32-NEXT:    [[TMP2:%.*]] = load bfloat, ptr [[C_ADDR]], align 2273// CHECK-LA32-NEXT:    [[C3:%.*]] = getelementptr inbounds nuw [[STRUCT_FLOATBFLOAT2]], ptr [[RETVAL]], i32 0, i32 2274// CHECK-LA32-NEXT:    store bfloat [[TMP2]], ptr [[C3]], align 2275// CHECK-LA32-NEXT:    [[TMP3:%.*]] = load [2 x i32], ptr [[RETVAL]], align 4276// CHECK-LA32-NEXT:    ret [2 x i32] [[TMP3]]277//278struct floatbfloat2 fh2(float a, __bf16 b, __bf16 c) {279  struct floatbfloat2 x;280  x.a = a;281  x.b = b;282  x.c = c;283  return x;284}285 286struct bfloatfloat {287  __bf16 a;288  float b;289};290 291// CHECK-LABEL: define dso_local { bfloat, float } @hf292// CHECK-SAME: (bfloat noundef [[A:%.*]], float noundef [[B:%.*]]) #[[ATTR0]] {293// CHECK-NEXT:  entry:294// CHECK-NEXT:    [[RETVAL:%.*]] = alloca [[STRUCT_BFLOATFLOAT:%.*]], align 4295// CHECK-NEXT:    [[A_ADDR:%.*]] = alloca bfloat, align 2296// CHECK-NEXT:    [[B_ADDR:%.*]] = alloca float, align 4297// CHECK-NEXT:    store bfloat [[A]], ptr [[A_ADDR]], align 2298// CHECK-NEXT:    store float [[B]], ptr [[B_ADDR]], align 4299// CHECK-NEXT:    [[TMP0:%.*]] = load bfloat, ptr [[A_ADDR]], align 2300// CHECK-NEXT:    [[A1:%.*]] = getelementptr inbounds nuw [[STRUCT_BFLOATFLOAT]], ptr [[RETVAL]], i32 0, i32 0301// CHECK-NEXT:    store bfloat [[TMP0]], ptr [[A1]], align 4302// CHECK-NEXT:    [[TMP1:%.*]] = load float, ptr [[B_ADDR]], align 4303// CHECK-NEXT:    [[B2:%.*]] = getelementptr inbounds nuw [[STRUCT_BFLOATFLOAT]], ptr [[RETVAL]], i32 0, i32 1304// CHECK-NEXT:    store float [[TMP1]], ptr [[B2]], align 4305// CHECK-NEXT:    [[TMP2:%.*]] = getelementptr inbounds nuw { bfloat, float }, ptr [[RETVAL]], i32 0, i32 0306// CHECK-NEXT:    [[TMP3:%.*]] = load bfloat, ptr [[TMP2]], align 4307// CHECK-NEXT:    [[TMP4:%.*]] = getelementptr inbounds nuw { bfloat, float }, ptr [[RETVAL]], i32 0, i32 1308// CHECK-NEXT:    [[TMP5:%.*]] = load float, ptr [[TMP4]], align 4309// CHECK-NEXT:    [[TMP6:%.*]] = insertvalue { bfloat, float } poison, bfloat [[TMP3]], 0310// CHECK-NEXT:    [[TMP7:%.*]] = insertvalue { bfloat, float } [[TMP6]], float [[TMP5]], 1311// CHECK-NEXT:    ret { bfloat, float } [[TMP7]]312//313struct bfloatfloat hf(__bf16 a, float b) {314  struct bfloatfloat x;315  x.a = a;316  x.b = b;317  return x;318}319 320struct bfloat2float {321  __bf16 a;322  __bf16 b;323  float c;324};325 326// CHECK-LA64-LABEL: define dso_local i64 @h2f327// CHECK-LA64-SAME: (bfloat noundef [[A:%.*]], bfloat noundef [[B:%.*]], float noundef [[C:%.*]]) #[[ATTR0]] {328// CHECK-LA64-NEXT:  entry:329// CHECK-LA64-NEXT:    [[RETVAL:%.*]] = alloca [[STRUCT_BFLOAT2FLOAT:%.*]], align 4330// CHECK-LA64-NEXT:    [[A_ADDR:%.*]] = alloca bfloat, align 2331// CHECK-LA64-NEXT:    [[B_ADDR:%.*]] = alloca bfloat, align 2332// CHECK-LA64-NEXT:    [[C_ADDR:%.*]] = alloca float, align 4333// CHECK-LA64-NEXT:    store bfloat [[A]], ptr [[A_ADDR]], align 2334// CHECK-LA64-NEXT:    store bfloat [[B]], ptr [[B_ADDR]], align 2335// CHECK-LA64-NEXT:    store float [[C]], ptr [[C_ADDR]], align 4336// CHECK-LA64-NEXT:    [[TMP0:%.*]] = load bfloat, ptr [[A_ADDR]], align 2337// CHECK-LA64-NEXT:    [[A1:%.*]] = getelementptr inbounds nuw [[STRUCT_BFLOAT2FLOAT]], ptr [[RETVAL]], i32 0, i32 0338// CHECK-LA64-NEXT:    store bfloat [[TMP0]], ptr [[A1]], align 4339// CHECK-LA64-NEXT:    [[TMP1:%.*]] = load bfloat, ptr [[B_ADDR]], align 2340// CHECK-LA64-NEXT:    [[B2:%.*]] = getelementptr inbounds nuw [[STRUCT_BFLOAT2FLOAT]], ptr [[RETVAL]], i32 0, i32 1341// CHECK-LA64-NEXT:    store bfloat [[TMP1]], ptr [[B2]], align 2342// CHECK-LA64-NEXT:    [[TMP2:%.*]] = load float, ptr [[C_ADDR]], align 4343// CHECK-LA64-NEXT:    [[C3:%.*]] = getelementptr inbounds nuw [[STRUCT_BFLOAT2FLOAT]], ptr [[RETVAL]], i32 0, i32 2344// CHECK-LA64-NEXT:    store float [[TMP2]], ptr [[C3]], align 4345// CHECK-LA64-NEXT:    [[TMP3:%.*]] = load i64, ptr [[RETVAL]], align 4346// CHECK-LA64-NEXT:    ret i64 [[TMP3]]347//348// CHECK-LA32-LABEL: define dso_local [2 x i32] @h2f349// CHECK-LA32-SAME: (bfloat noundef [[A:%.*]], bfloat noundef [[B:%.*]], float noundef [[C:%.*]]) #[[ATTR0]] {350// CHECK-LA32-NEXT:  entry:351// CHECK-LA32-NEXT:    [[RETVAL:%.*]] = alloca [[STRUCT_BFLOAT2FLOAT:%.*]], align 4352// CHECK-LA32-NEXT:    [[A_ADDR:%.*]] = alloca bfloat, align 2353// CHECK-LA32-NEXT:    [[B_ADDR:%.*]] = alloca bfloat, align 2354// CHECK-LA32-NEXT:    [[C_ADDR:%.*]] = alloca float, align 4355// CHECK-LA32-NEXT:    store bfloat [[A]], ptr [[A_ADDR]], align 2356// CHECK-LA32-NEXT:    store bfloat [[B]], ptr [[B_ADDR]], align 2357// CHECK-LA32-NEXT:    store float [[C]], ptr [[C_ADDR]], align 4358// CHECK-LA32-NEXT:    [[TMP0:%.*]] = load bfloat, ptr [[A_ADDR]], align 2359// CHECK-LA32-NEXT:    [[A1:%.*]] = getelementptr inbounds nuw [[STRUCT_BFLOAT2FLOAT]], ptr [[RETVAL]], i32 0, i32 0360// CHECK-LA32-NEXT:    store bfloat [[TMP0]], ptr [[A1]], align 4361// CHECK-LA32-NEXT:    [[TMP1:%.*]] = load bfloat, ptr [[B_ADDR]], align 2362// CHECK-LA32-NEXT:    [[B2:%.*]] = getelementptr inbounds nuw [[STRUCT_BFLOAT2FLOAT]], ptr [[RETVAL]], i32 0, i32 1363// CHECK-LA32-NEXT:    store bfloat [[TMP1]], ptr [[B2]], align 2364// CHECK-LA32-NEXT:    [[TMP2:%.*]] = load float, ptr [[C_ADDR]], align 4365// CHECK-LA32-NEXT:    [[C3:%.*]] = getelementptr inbounds nuw [[STRUCT_BFLOAT2FLOAT]], ptr [[RETVAL]], i32 0, i32 2366// CHECK-LA32-NEXT:    store float [[TMP2]], ptr [[C3]], align 4367// CHECK-LA32-NEXT:    [[TMP3:%.*]] = load [2 x i32], ptr [[RETVAL]], align 4368// CHECK-LA32-NEXT:    ret [2 x i32] [[TMP3]]369//370struct bfloat2float h2f(__bf16 a, __bf16 b, float c) {371  struct bfloat2float x;372  x.a = a;373  x.b = b;374  x.c = c;375  return x;376}377 378struct floatbfloat3 {379  float a;380  __bf16 b;381  __bf16 c;382  __bf16 d;383};384 385// CHECK-LA64-LABEL: define dso_local [2 x i64] @fh3386// CHECK-LA64-SAME: (float noundef [[A:%.*]], bfloat noundef [[B:%.*]], bfloat noundef [[C:%.*]], bfloat noundef [[D:%.*]]) #[[ATTR0]] {387// CHECK-LA64-NEXT:  entry:388// CHECK-LA64-NEXT:    [[RETVAL:%.*]] = alloca [[STRUCT_FLOATBFLOAT3:%.*]], align 4389// CHECK-LA64-NEXT:    [[A_ADDR:%.*]] = alloca float, align 4390// CHECK-LA64-NEXT:    [[B_ADDR:%.*]] = alloca bfloat, align 2391// CHECK-LA64-NEXT:    [[C_ADDR:%.*]] = alloca bfloat, align 2392// CHECK-LA64-NEXT:    [[D_ADDR:%.*]] = alloca bfloat, align 2393// CHECK-LA64-NEXT:    [[RETVAL_COERCE:%.*]] = alloca [2 x i64], align 8394// CHECK-LA64-NEXT:    store float [[A]], ptr [[A_ADDR]], align 4395// CHECK-LA64-NEXT:    store bfloat [[B]], ptr [[B_ADDR]], align 2396// CHECK-LA64-NEXT:    store bfloat [[C]], ptr [[C_ADDR]], align 2397// CHECK-LA64-NEXT:    store bfloat [[D]], ptr [[D_ADDR]], align 2398// CHECK-LA64-NEXT:    [[TMP0:%.*]] = load float, ptr [[A_ADDR]], align 4399// CHECK-LA64-NEXT:    [[A1:%.*]] = getelementptr inbounds nuw [[STRUCT_FLOATBFLOAT3]], ptr [[RETVAL]], i32 0, i32 0400// CHECK-LA64-NEXT:    store float [[TMP0]], ptr [[A1]], align 4401// CHECK-LA64-NEXT:    [[TMP1:%.*]] = load bfloat, ptr [[B_ADDR]], align 2402// CHECK-LA64-NEXT:    [[B2:%.*]] = getelementptr inbounds nuw [[STRUCT_FLOATBFLOAT3]], ptr [[RETVAL]], i32 0, i32 1403// CHECK-LA64-NEXT:    store bfloat [[TMP1]], ptr [[B2]], align 4404// CHECK-LA64-NEXT:    [[TMP2:%.*]] = load bfloat, ptr [[C_ADDR]], align 2405// CHECK-LA64-NEXT:    [[C3:%.*]] = getelementptr inbounds nuw [[STRUCT_FLOATBFLOAT3]], ptr [[RETVAL]], i32 0, i32 2406// CHECK-LA64-NEXT:    store bfloat [[TMP2]], ptr [[C3]], align 2407// CHECK-LA64-NEXT:    [[TMP3:%.*]] = load bfloat, ptr [[D_ADDR]], align 2408// CHECK-LA64-NEXT:    [[D4:%.*]] = getelementptr inbounds nuw [[STRUCT_FLOATBFLOAT3]], ptr [[RETVAL]], i32 0, i32 3409// CHECK-LA64-NEXT:    store bfloat [[TMP3]], ptr [[D4]], align 4410// CHECK-LA64-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[RETVAL_COERCE]], ptr align 4 [[RETVAL]], i64 12, i1 false)411// CHECK-LA64-NEXT:    [[TMP4:%.*]] = load [2 x i64], ptr [[RETVAL_COERCE]], align 8412// CHECK-LA64-NEXT:    ret [2 x i64] [[TMP4]]413//414// CHECK-LA32-LABEL: define dso_local void @fh3415// CHECK-LA32-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_FLOATBFLOAT3:%.*]]) align 4 [[AGG_RESULT:%.*]], float noundef [[A:%.*]], bfloat noundef [[B:%.*]], bfloat noundef [[C:%.*]], bfloat noundef [[D:%.*]]) #[[ATTR0]] {416// CHECK-LA32-NEXT:  entry:417// CHECK-LA32-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 4418// CHECK-LA32-NEXT:    [[A_ADDR:%.*]] = alloca float, align 4419// CHECK-LA32-NEXT:    [[B_ADDR:%.*]] = alloca bfloat, align 2420// CHECK-LA32-NEXT:    [[C_ADDR:%.*]] = alloca bfloat, align 2421// CHECK-LA32-NEXT:    [[D_ADDR:%.*]] = alloca bfloat, align 2422// CHECK-LA32-NEXT:    store ptr [[AGG_RESULT]], ptr [[RESULT_PTR]], align 4423// CHECK-LA32-NEXT:    store float [[A]], ptr [[A_ADDR]], align 4424// CHECK-LA32-NEXT:    store bfloat [[B]], ptr [[B_ADDR]], align 2425// CHECK-LA32-NEXT:    store bfloat [[C]], ptr [[C_ADDR]], align 2426// CHECK-LA32-NEXT:    store bfloat [[D]], ptr [[D_ADDR]], align 2427// CHECK-LA32-NEXT:    [[TMP0:%.*]] = load float, ptr [[A_ADDR]], align 4428// CHECK-LA32-NEXT:    [[A1:%.*]] = getelementptr inbounds nuw [[STRUCT_FLOATBFLOAT3]], ptr [[AGG_RESULT]], i32 0, i32 0429// CHECK-LA32-NEXT:    store float [[TMP0]], ptr [[A1]], align 4430// CHECK-LA32-NEXT:    [[TMP1:%.*]] = load bfloat, ptr [[B_ADDR]], align 2431// CHECK-LA32-NEXT:    [[B2:%.*]] = getelementptr inbounds nuw [[STRUCT_FLOATBFLOAT3]], ptr [[AGG_RESULT]], i32 0, i32 1432// CHECK-LA32-NEXT:    store bfloat [[TMP1]], ptr [[B2]], align 4433// CHECK-LA32-NEXT:    [[TMP2:%.*]] = load bfloat, ptr [[C_ADDR]], align 2434// CHECK-LA32-NEXT:    [[C3:%.*]] = getelementptr inbounds nuw [[STRUCT_FLOATBFLOAT3]], ptr [[AGG_RESULT]], i32 0, i32 2435// CHECK-LA32-NEXT:    store bfloat [[TMP2]], ptr [[C3]], align 2436// CHECK-LA32-NEXT:    [[TMP3:%.*]] = load bfloat, ptr [[D_ADDR]], align 2437// CHECK-LA32-NEXT:    [[D4:%.*]] = getelementptr inbounds nuw [[STRUCT_FLOATBFLOAT3]], ptr [[AGG_RESULT]], i32 0, i32 3438// CHECK-LA32-NEXT:    store bfloat [[TMP3]], ptr [[D4]], align 4439// CHECK-LA32-NEXT:    ret void440//441struct floatbfloat3 fh3(float a, __bf16 b, __bf16 c, __bf16 d) {442  struct floatbfloat3 x;443  x.a = a;444  x.b = b;445  x.c = c;446  x.d = d;447  return x;448}449 450struct bfloat5 {451  __bf16 a;452  __bf16 b;453  __bf16 c;454  __bf16 d;455  __bf16 e;456};457 458// CHECK-LA64-LABEL: define dso_local [2 x i64] @h5459// CHECK-LA64-SAME: (bfloat noundef [[A:%.*]], bfloat noundef [[B:%.*]], bfloat noundef [[C:%.*]], bfloat noundef [[D:%.*]], bfloat noundef [[E:%.*]]) #[[ATTR0]] {460// CHECK-LA64-NEXT:  entry:461// CHECK-LA64-NEXT:    [[RETVAL:%.*]] = alloca [[STRUCT_BFLOAT5:%.*]], align 2462// CHECK-LA64-NEXT:    [[A_ADDR:%.*]] = alloca bfloat, align 2463// CHECK-LA64-NEXT:    [[B_ADDR:%.*]] = alloca bfloat, align 2464// CHECK-LA64-NEXT:    [[C_ADDR:%.*]] = alloca bfloat, align 2465// CHECK-LA64-NEXT:    [[D_ADDR:%.*]] = alloca bfloat, align 2466// CHECK-LA64-NEXT:    [[E_ADDR:%.*]] = alloca bfloat, align 2467// CHECK-LA64-NEXT:    [[RETVAL_COERCE:%.*]] = alloca [2 x i64], align 8468// CHECK-LA64-NEXT:    store bfloat [[A]], ptr [[A_ADDR]], align 2469// CHECK-LA64-NEXT:    store bfloat [[B]], ptr [[B_ADDR]], align 2470// CHECK-LA64-NEXT:    store bfloat [[C]], ptr [[C_ADDR]], align 2471// CHECK-LA64-NEXT:    store bfloat [[D]], ptr [[D_ADDR]], align 2472// CHECK-LA64-NEXT:    store bfloat [[E]], ptr [[E_ADDR]], align 2473// CHECK-LA64-NEXT:    [[TMP0:%.*]] = load bfloat, ptr [[A_ADDR]], align 2474// CHECK-LA64-NEXT:    [[A1:%.*]] = getelementptr inbounds nuw [[STRUCT_BFLOAT5]], ptr [[RETVAL]], i32 0, i32 0475// CHECK-LA64-NEXT:    store bfloat [[TMP0]], ptr [[A1]], align 2476// CHECK-LA64-NEXT:    [[TMP1:%.*]] = load bfloat, ptr [[B_ADDR]], align 2477// CHECK-LA64-NEXT:    [[B2:%.*]] = getelementptr inbounds nuw [[STRUCT_BFLOAT5]], ptr [[RETVAL]], i32 0, i32 1478// CHECK-LA64-NEXT:    store bfloat [[TMP1]], ptr [[B2]], align 2479// CHECK-LA64-NEXT:    [[TMP2:%.*]] = load bfloat, ptr [[C_ADDR]], align 2480// CHECK-LA64-NEXT:    [[C3:%.*]] = getelementptr inbounds nuw [[STRUCT_BFLOAT5]], ptr [[RETVAL]], i32 0, i32 2481// CHECK-LA64-NEXT:    store bfloat [[TMP2]], ptr [[C3]], align 2482// CHECK-LA64-NEXT:    [[TMP3:%.*]] = load bfloat, ptr [[D_ADDR]], align 2483// CHECK-LA64-NEXT:    [[D4:%.*]] = getelementptr inbounds nuw [[STRUCT_BFLOAT5]], ptr [[RETVAL]], i32 0, i32 3484// CHECK-LA64-NEXT:    store bfloat [[TMP3]], ptr [[D4]], align 2485// CHECK-LA64-NEXT:    [[TMP4:%.*]] = load bfloat, ptr [[E_ADDR]], align 2486// CHECK-LA64-NEXT:    [[E5:%.*]] = getelementptr inbounds nuw [[STRUCT_BFLOAT5]], ptr [[RETVAL]], i32 0, i32 4487// CHECK-LA64-NEXT:    store bfloat [[TMP4]], ptr [[E5]], align 2488// CHECK-LA64-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[RETVAL_COERCE]], ptr align 2 [[RETVAL]], i64 10, i1 false)489// CHECK-LA64-NEXT:    [[TMP5:%.*]] = load [2 x i64], ptr [[RETVAL_COERCE]], align 8490// CHECK-LA64-NEXT:    ret [2 x i64] [[TMP5]]491//492// CHECK-LA32-LABEL: define dso_local void @h5493// CHECK-LA32-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_BFLOAT5:%.*]]) align 2 [[AGG_RESULT:%.*]], bfloat noundef [[A:%.*]], bfloat noundef [[B:%.*]], bfloat noundef [[C:%.*]], bfloat noundef [[D:%.*]], bfloat noundef [[E:%.*]]) #[[ATTR0]] {494// CHECK-LA32-NEXT:  entry:495// CHECK-LA32-NEXT:    [[RESULT_PTR:%.*]] = alloca ptr, align 4496// CHECK-LA32-NEXT:    [[A_ADDR:%.*]] = alloca bfloat, align 2497// CHECK-LA32-NEXT:    [[B_ADDR:%.*]] = alloca bfloat, align 2498// CHECK-LA32-NEXT:    [[C_ADDR:%.*]] = alloca bfloat, align 2499// CHECK-LA32-NEXT:    [[D_ADDR:%.*]] = alloca bfloat, align 2500// CHECK-LA32-NEXT:    [[E_ADDR:%.*]] = alloca bfloat, align 2501// CHECK-LA32-NEXT:    store ptr [[AGG_RESULT]], ptr [[RESULT_PTR]], align 4502// CHECK-LA32-NEXT:    store bfloat [[A]], ptr [[A_ADDR]], align 2503// CHECK-LA32-NEXT:    store bfloat [[B]], ptr [[B_ADDR]], align 2504// CHECK-LA32-NEXT:    store bfloat [[C]], ptr [[C_ADDR]], align 2505// CHECK-LA32-NEXT:    store bfloat [[D]], ptr [[D_ADDR]], align 2506// CHECK-LA32-NEXT:    store bfloat [[E]], ptr [[E_ADDR]], align 2507// CHECK-LA32-NEXT:    [[TMP0:%.*]] = load bfloat, ptr [[A_ADDR]], align 2508// CHECK-LA32-NEXT:    [[A1:%.*]] = getelementptr inbounds nuw [[STRUCT_BFLOAT5]], ptr [[AGG_RESULT]], i32 0, i32 0509// CHECK-LA32-NEXT:    store bfloat [[TMP0]], ptr [[A1]], align 2510// CHECK-LA32-NEXT:    [[TMP1:%.*]] = load bfloat, ptr [[B_ADDR]], align 2511// CHECK-LA32-NEXT:    [[B2:%.*]] = getelementptr inbounds nuw [[STRUCT_BFLOAT5]], ptr [[AGG_RESULT]], i32 0, i32 1512// CHECK-LA32-NEXT:    store bfloat [[TMP1]], ptr [[B2]], align 2513// CHECK-LA32-NEXT:    [[TMP2:%.*]] = load bfloat, ptr [[C_ADDR]], align 2514// CHECK-LA32-NEXT:    [[C3:%.*]] = getelementptr inbounds nuw [[STRUCT_BFLOAT5]], ptr [[AGG_RESULT]], i32 0, i32 2515// CHECK-LA32-NEXT:    store bfloat [[TMP2]], ptr [[C3]], align 2516// CHECK-LA32-NEXT:    [[TMP3:%.*]] = load bfloat, ptr [[D_ADDR]], align 2517// CHECK-LA32-NEXT:    [[D4:%.*]] = getelementptr inbounds nuw [[STRUCT_BFLOAT5]], ptr [[AGG_RESULT]], i32 0, i32 3518// CHECK-LA32-NEXT:    store bfloat [[TMP3]], ptr [[D4]], align 2519// CHECK-LA32-NEXT:    [[TMP4:%.*]] = load bfloat, ptr [[E_ADDR]], align 2520// CHECK-LA32-NEXT:    [[E5:%.*]] = getelementptr inbounds nuw [[STRUCT_BFLOAT5]], ptr [[AGG_RESULT]], i32 0, i32 4521// CHECK-LA32-NEXT:    store bfloat [[TMP4]], ptr [[E5]], align 2522// CHECK-LA32-NEXT:    ret void523//524struct bfloat5 h5(__bf16 a, __bf16 b, __bf16 c, __bf16 d, __bf16 e) {525  struct bfloat5 x;526  x.a = a;527  x.b = b;528  x.c = c;529  x.d = d;530  x.e = e;531  return x;532}533