318 lines · cpp
1// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-cir %s -o %t.cir2// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR3// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-llvm %s -o %t-cir.ll4// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM5// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -Wno-unused-value -emit-llvm %s -o %t.ll6// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG7 8void foo() {9 int _Complex a;10 int _Complex b;11 int _Complex c = a + b;12}13 14// CIR: %[[A_ADDR:.*]] = cir.alloca !cir.complex<!s32i>, !cir.ptr<!cir.complex<!s32i>>, ["a"]15// CIR: %[[B_ADDR:.*]] = cir.alloca !cir.complex<!s32i>, !cir.ptr<!cir.complex<!s32i>>, ["b"]16// CIR: %[[TMP_A:.*]] = cir.load{{.*}} %[[A_ADDR]] : !cir.ptr<!cir.complex<!s32i>>, !cir.complex<!s32i>17// CIR: %[[TMP_B:.*]] = cir.load{{.*}} %[[B_ADDR]] : !cir.ptr<!cir.complex<!s32i>>, !cir.complex<!s32i>18// CIR: %[[ADD:.*]] = cir.complex.add %[[TMP_A]], %[[TMP_B]] : !cir.complex<!s32i>19 20// LLVM: %[[A_ADDR:.*]] = alloca { i32, i32 }, i64 1, align 421// LLVM: %[[B_ADDR:.*]] = alloca { i32, i32 }, i64 1, align 422// LLVM: %[[TMP_A:.*]] = load { i32, i32 }, ptr %[[A_ADDR]], align 423// LLVM: %[[TMP_B:.*]] = load { i32, i32 }, ptr %[[B_ADDR]], align 424// LLVM: %[[A_REAL:.*]] = extractvalue { i32, i32 } %[[TMP_A]], 025// LLVM: %[[A_IMAG:.*]] = extractvalue { i32, i32 } %[[TMP_A]], 126// LLVM: %[[B_REAL:.*]] = extractvalue { i32, i32 } %[[TMP_B]], 027// LLVM: %[[B_IMAG:.*]] = extractvalue { i32, i32 } %[[TMP_B]], 128// LLVM: %[[ADD_REAL:.*]] = add i32 %[[A_REAL]], %[[B_REAL]]29// LLVM: %[[ADD_IMAG:.*]] = add i32 %[[A_IMAG]], %[[B_IMAG]]30// LLVM: %[[RESULT:.*]] = insertvalue { i32, i32 } poison, i32 %[[ADD_REAL]], 031// LLVM: %[[RESULT_2:.*]] = insertvalue { i32, i32 } %[[RESULT]], i32 %[[ADD_IMAG]], 132 33// OGCG: %[[A_ADDR:.*]] = alloca { i32, i32 }, align 434// OGCG: %[[B_ADDR:.*]] = alloca { i32, i32 }, align 435// OGCG: %[[RESULT:.*]] = alloca { i32, i32 }, align 436// OGCG: %[[A_REAL_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[A_ADDR]], i32 0, i32 037// OGCG: %[[A_REAL:.*]] = load i32, ptr %[[A_REAL_PTR]], align 438// OGCG: %[[A_IMAG_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[A_ADDR]], i32 0, i32 139// OGCG: %[[A_IMAG:.*]] = load i32, ptr %[[A_IMAG_PTR]], align 440// OGCG: %[[B_REAL_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[B_ADDR]], i32 0, i32 041// OGCG: %[[B_REAL:.*]] = load i32, ptr %[[B_REAL_PTR]], align 442// OGCG: %[[B_IMAG_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[B_ADDR]], i32 0, i32 143// OGCG: %[[B_IMAG:.*]] = load i32, ptr %[[B_IMAG_PTR]], align 444// OGCG: %[[ADD_REAL:.*]] = add i32 %[[A_REAL]], %[[B_REAL]]45// OGCG: %[[ADD_IMAG:.*]] = add i32 %[[A_IMAG]], %[[B_IMAG]]46// OGCG: %[[RESULT_REAL_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[RESULT]], i32 0, i32 047// OGCG: %[[RESULT_IMAG_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[RESULT]], i32 0, i32 148// OGCG: store i32 %[[ADD_REAL]], ptr %[[RESULT_REAL_PTR]], align 449// OGCG: store i32 %[[ADD_IMAG]], ptr %[[RESULT_IMAG_PTR]], align 450 51void foo2() {52 float _Complex a;53 float _Complex b;54 float _Complex c = a + b;55}56 57// CIR: %[[A_ADDR:.*]] = cir.alloca !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>, ["a"]58// CIR: %[[B_ADDR:.*]] = cir.alloca !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>, ["b"]59// CIR: %[[TMP_A:.*]] = cir.load{{.*}} %[[A_ADDR]] : !cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float>60// CIR: %[[TMP_B:.*]] = cir.load{{.*}} %[[B_ADDR]] : !cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float>61// CIR: %[[ADD:.*]] = cir.complex.add %[[TMP_A]], %[[TMP_B]] : !cir.complex<!cir.float>62 63// LLVM: %[[A_ADDR:.*]] = alloca { float, float }, i64 1, align 464// LLVM: %[[B_ADDR:.*]] = alloca { float, float }, i64 1, align 465// LLVM: %[[TMP_A:.*]] = load { float, float }, ptr %[[A_ADDR]], align 466// LLVM: %[[TMP_B:.*]] = load { float, float }, ptr %[[B_ADDR]], align 467// LLVM: %[[A_REAL:.*]] = extractvalue { float, float } %[[TMP_A]], 068// LLVM: %[[A_IMAG:.*]] = extractvalue { float, float } %[[TMP_A]], 169// LLVM: %[[B_REAL:.*]] = extractvalue { float, float } %[[TMP_B]], 070// LLVM: %[[B_IMAG:.*]] = extractvalue { float, float } %[[TMP_B]], 171// LLVM: %[[ADD_REAL:.*]] = fadd float %[[A_REAL]], %[[B_REAL]]72// LLVM: %[[ADD_IMAG:.*]] = fadd float %[[A_IMAG]], %[[B_IMAG]]73// LLVM: %[[RESULT:.*]] = insertvalue { float, float } poison, float %[[ADD_REAL]], 074// LLVM: %[[RESULT_2:.*]] = insertvalue { float, float } %[[RESULT]], float %[[ADD_IMAG]], 175 76// OGCG: %[[A_ADDR:.*]] = alloca { float, float }, align 477// OGCG: %[[B_ADDR:.*]] = alloca { float, float }, align 478// OGCG: %[[RESULT:.*]] = alloca { float, float }, align 479// OGCG: %[[A_REAL_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[A_ADDR]], i32 0, i32 080// OGCG: %[[A_REAL:.*]] = load float, ptr %[[A_REAL_PTR]], align 481// OGCG: %[[A_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[A_ADDR]], i32 0, i32 182// OGCG: %[[A_IMAG:.*]] = load float, ptr %[[A_IMAG_PTR]], align 483// OGCG: %[[B_REAL_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[B_ADDR]], i32 0, i32 084// OGCG: %[[B_REAL:.*]] = load float, ptr %[[B_REAL_PTR]], align 485// OGCG: %[[B_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[B_ADDR]], i32 0, i32 186// OGCG: %[[B_IMAG:.*]] = load float, ptr %[[B_IMAG_PTR]], align 487// OGCG: %[[ADD_REAL:.*]] = fadd float %[[A_REAL]], %[[B_REAL]]88// OGCG: %[[ADD_IMAG:.*]] = fadd float %[[A_IMAG]], %[[B_IMAG]]89// OGCG: %[[RESULT_REAL_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[RESULT]], i32 0, i32 090// OGCG: %[[RESULT_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[RESULT]], i32 0, i32 191// OGCG: store float %[[ADD_REAL]], ptr %[[RESULT_REAL_PTR]], align 492// OGCG: store float %[[ADD_IMAG]], ptr %[[RESULT_IMAG_PTR]], align 493 94void foo3() {95 float _Complex a;96 float _Complex b;97 float _Complex c;98 float _Complex d = (a + b) + c;99}100 101// CIR: %[[A_ADDR:.*]] = cir.alloca !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>, ["a"]102// CIR: %[[B_ADDR:.*]] = cir.alloca !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>, ["b"]103// CIR: %[[C_ADDR:.*]] = cir.alloca !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>, ["c"]104// CIR: %[[RESULT:.*]] = cir.alloca !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>, ["d", init]105// CIR: %[[TMP_A:.*]] = cir.load{{.*}} %[[A_ADDR]] : !cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float>106// CIR: %[[TMP_B:.*]] = cir.load{{.*}} %[[B_ADDR]] : !cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float>107// CIR: %[[ADD_A_B:.*]] = cir.complex.add %[[TMP_A]], %[[TMP_B]] : !cir.complex<!cir.float>108// CIR: %[[TMP_C:.*]] = cir.load{{.*}} %[[C_ADDR]] : !cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float>109// CIR: %[[ADD_A_B_C:.*]] = cir.complex.add %[[ADD_A_B]], %[[TMP_C]] : !cir.complex<!cir.float>110// CIR: cir.store{{.*}} %[[ADD_A_B_C]], %[[RESULT]] : !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>111 112// LLVM: %[[A_ADDR:.*]] = alloca { float, float }, i64 1, align 4113// LLVM: %[[B_ADDR:.*]] = alloca { float, float }, i64 1, align 4114// LLVM: %[[C_ADDR:.*]] = alloca { float, float }, i64 1, align 4115// LLVM: %[[RESULT:.*]] = alloca { float, float }, i64 1, align 4116// LLVM: %[[TMP_A:.*]] = load { float, float }, ptr %[[A_ADDR]], align 4117// LLVM: %[[TMP_B:.*]] = load { float, float }, ptr %[[B_ADDR]], align 4118// LLVM: %[[A_REAL:.*]] = extractvalue { float, float } %[[TMP_A]], 0119// LLVM: %[[A_IMAG:.*]] = extractvalue { float, float } %[[TMP_A]], 1120// LLVM: %[[B_REAL:.*]] = extractvalue { float, float } %[[TMP_B]], 0121// LLVM: %[[B_IMAG:.*]] = extractvalue { float, float } %[[TMP_B]], 1122// LLVM: %[[ADD_REAL_A_B:.*]] = fadd float %[[A_REAL]], %[[B_REAL]]123// LLVM: %[[ADD_IMAG_A_B:.*]] = fadd float %[[A_IMAG]], %[[B_IMAG]]124// LLVM: %[[A_B:.*]] = insertvalue { float, float } poison, float %[[ADD_REAL_A_B]], 0125// LLVM: %[[TMP_A_B:.*]] = insertvalue { float, float } %[[A_B]], float %[[ADD_IMAG_A_B]], 1126// LLVM: %[[TMP_C:.*]] = load { float, float }, ptr %[[C_ADDR]], align 4127// LLVM: %[[A_B_REAL:.*]] = extractvalue { float, float } %[[TMP_A_B]], 0128// LLVM: %[[A_B_IMAG:.*]] = extractvalue { float, float } %[[TMP_A_B]], 1129// LLVM: %[[C_REAL:.*]] = extractvalue { float, float } %[[TMP_C]], 0130// LLVM: %[[C_IMAG:.*]] = extractvalue { float, float } %[[TMP_C]], 1131// LLVM: %[[ADD_REAL_A_B_C:.*]] = fadd float %[[A_B_REAL]], %[[C_REAL]]132// LLVM: %[[ADD_IMAG_A_B_C:.*]] = fadd float %[[A_B_IMAG]], %[[C_IMAG]]133// LLVM: %[[A_B_C:.*]] = insertvalue { float, float } poison, float %[[ADD_REAL_A_B_C]], 0134// LLVM: %[[TMP_A_B_C:.*]] = insertvalue { float, float } %[[A_B_C]], float %[[ADD_IMAG_A_B_C]], 1135// LLVM: store { float, float } %[[TMP_A_B_C]], ptr %[[RESULT]], align 4136 137// OGCG: %[[A_ADDR:.*]] = alloca { float, float }, align 4138// OGCG: %[[B_ADDR:.*]] = alloca { float, float }, align 4139// OGCG: %[[C_ADDR:.*]] = alloca { float, float }, align 4140// OGCG: %[[RESULT:.*]] = alloca { float, float }, align 4141// OGCG: %[[A_REAL_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[A_ADDR]], i32 0, i32 0142// OGCG: %[[A_REAL:.*]] = load float, ptr %[[A_REAL_PTR]], align 4143// OGCG: %[[A_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[A_ADDR]], i32 0, i32 1144// OGCG: %[[A_IMAG:.*]] = load float, ptr %[[A_IMAG_PTR]], align 4145// OGCG: %[[B_REAL_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[B_ADDR]], i32 0, i32 0146// OGCG: %[[B_REAL:.*]] = load float, ptr %[[B_REAL_PTR]], align 4147// OGCG: %[[B_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[B_ADDR]], i32 0, i32 1148// OGCG: %[[B_IMAG:.*]] = load float, ptr %[[B_IMAG_PTR]], align 4149// OGCG: %[[ADD_REAL_A_B:.*]] = fadd float %[[A_REAL]], %[[B_REAL]]150// OGCG: %[[ADD_IMAG_A_B:.*]] = fadd float %[[A_IMAG]], %[[B_IMAG]]151// OGCG: %[[C_REAL_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[C_ADDR]], i32 0, i32 0152// OGCG: %[[C_REAL:.*]] = load float, ptr %[[C_REAL_PTR]], align 4153// OGCG: %[[C_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[C_ADDR]], i32 0, i32 1154// OGCG: %[[C_IMAG:.*]] = load float, ptr %[[C_IMAG_PTR]], align 4155// OGCG: %[[ADD_REAL_A_B_C:.*]] = fadd float %[[ADD_REAL_A_B]], %[[C_REAL]]156// OGCG: %[[ADD_IMAG_A_B_C:.*]] = fadd float %[[ADD_IMAG_A_B]], %[[C_IMAG]]157// OGCG: %[[RESULT_REAL_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[RESULT]], i32 0, i32 0158// OGCG: %[[RESULT_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[RESULT]], i32 0, i32 1159// OGCG: store float %[[ADD_REAL_A_B_C]], ptr %[[RESULT_REAL_PTR]], align 4160// OGCG: store float %[[ADD_IMAG_A_B_C]], ptr %[[RESULT_IMAG_PTR]], align 4161 162void foo4() {163 int _Complex a;164 int _Complex b;165 int _Complex c = a - b;166}167 168// CIR: %[[A_ADDR:.*]] = cir.alloca !cir.complex<!s32i>, !cir.ptr<!cir.complex<!s32i>>, ["a"]169// CIR: %[[B_ADDR:.*]] = cir.alloca !cir.complex<!s32i>, !cir.ptr<!cir.complex<!s32i>>, ["b"]170// CIR: %[[TMP_A:.*]] = cir.load{{.*}} %[[A_ADDR]] : !cir.ptr<!cir.complex<!s32i>>, !cir.complex<!s32i>171// CIR: %[[TMP_B:.*]] = cir.load{{.*}} %[[B_ADDR]] : !cir.ptr<!cir.complex<!s32i>>, !cir.complex<!s32i>172// CIR: %[[SUB:.*]] = cir.complex.sub %[[TMP_A]], %[[TMP_B]] : !cir.complex<!s32i>173 174// LLVM: %[[A_ADDR:.*]] = alloca { i32, i32 }, i64 1, align 4175// LLVM: %[[B_ADDR:.*]] = alloca { i32, i32 }, i64 1, align 4176// LLVM: %[[C_ADDR:.*]] = alloca { i32, i32 }, i64 1, align 4177// LLVM: %[[TMP_A:.*]] = load { i32, i32 }, ptr %[[A_ADDR]], align 4178// LLVM: %[[TMP_B:.*]] = load { i32, i32 }, ptr %[[B_ADDR]], align 4179// LLVM: %[[A_REAL:.*]] = extractvalue { i32, i32 } %[[TMP_A]], 0180// LLVM: %[[A_IMAG:.*]] = extractvalue { i32, i32 } %[[TMP_A]], 1181// LLVM: %[[B_REAL:.*]] = extractvalue { i32, i32 } %[[TMP_B]], 0182// LLVM: %[[B_IMAG:.*]] = extractvalue { i32, i32 } %[[TMP_B]], 1183// LLVM: %[[SUB_REAL:.*]] = sub i32 %[[A_REAL]], %[[B_REAL]]184// LLVM: %[[SUB_IMAG:.*]] = sub i32 %[[A_IMAG]], %[[B_IMAG]]185// LLVM: %[[RESULT:.*]] = insertvalue { i32, i32 } poison, i32 %[[SUB_REAL]], 0186// LLVM: %[[RESULT_2:.*]] = insertvalue { i32, i32 } %[[RESULT]], i32 %[[SUB_IMAG]], 1187// LLVM: store { i32, i32 } %[[RESULT_2]], ptr %[[C_ADDR]], align 4188 189// OGCG: %[[A_ADDR:.*]] = alloca { i32, i32 }, align 4190// OGCG: %[[B_ADDR:.*]] = alloca { i32, i32 }, align 4191// OGCG: %[[RESULT:.*]] = alloca { i32, i32 }, align 4192// OGCG: %[[A_REAL_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[A_ADDR]], i32 0, i32 0193// OGCG: %[[A_REAL:.*]] = load i32, ptr %[[A_REAL_PTR]], align 4194// OGCG: %[[A_IMAG_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[A_ADDR]], i32 0, i32 1195// OGCG: %[[A_IMAG:.*]] = load i32, ptr %[[A_IMAG_PTR]], align 4196// OGCG: %[[B_REAL_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[B_ADDR]], i32 0, i32 0197// OGCG: %[[B_REAL:.*]] = load i32, ptr %[[B_REAL_PTR]], align 4198// OGCG: %[[B_IMAG_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[B_ADDR]], i32 0, i32 1199// OGCG: %[[B_IMAG:.*]] = load i32, ptr %[[B_IMAG_PTR]], align 4200// OGCG: %[[SUB_REAL:.*]] = sub i32 %[[A_REAL]], %[[B_REAL]]201// OGCG: %[[SUB_IMAG:.*]] = sub i32 %[[A_IMAG]], %[[B_IMAG]]202// OGCG: %[[RESULT_REAL_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[RESULT]], i32 0, i32 0203// OGCG: %[[RESULT_IMAG_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[RESULT]], i32 0, i32 1204// OGCG: store i32 %[[SUB_REAL]], ptr %[[RESULT_REAL_PTR]], align 4205// OGCG: store i32 %[[SUB_IMAG]], ptr %[[RESULT_IMAG_PTR]], align 4206 207void foo5() {208 float _Complex a;209 float _Complex b;210 float _Complex c = a - b;211}212 213// CIR: %[[A_ADDR:.*]] = cir.alloca !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>, ["a"]214// CIR: %[[B_ADDR:.*]] = cir.alloca !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>, ["b"]215// CIR: %[[TMP_A:.*]] = cir.load{{.*}} %[[A_ADDR]] : !cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float>216// CIR: %[[TMP_B:.*]] = cir.load{{.*}} %[[B_ADDR]] : !cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float>217// CIR: %[[SUB:.*]] = cir.complex.sub %[[TMP_A]], %[[TMP_B]] : !cir.complex<!cir.float>218 219// LLVM: %[[A_ADDR:.*]] = alloca { float, float }, i64 1, align 4220// LLVM: %[[B_ADDR:.*]] = alloca { float, float }, i64 1, align 4221// LLVM: %[[TMP_A:.*]] = load { float, float }, ptr %[[A_ADDR]], align 4222// LLVM: %[[TMP_B:.*]] = load { float, float }, ptr %[[B_ADDR]], align 4223// LLVM: %[[A_REAL:.*]] = extractvalue { float, float } %[[TMP_A]], 0224// LLVM: %[[A_IMAG:.*]] = extractvalue { float, float } %[[TMP_A]], 1225// LLVM: %[[B_REAL:.*]] = extractvalue { float, float } %[[TMP_B]], 0226// LLVM: %[[B_IMAG:.*]] = extractvalue { float, float } %[[TMP_B]], 1227// LLVM: %[[SUB_REAL:.*]] = fsub float %[[A_REAL]], %[[B_REAL]]228// LLVM: %[[SUB_IMAG:.*]] = fsub float %[[A_IMAG]], %[[B_IMAG]]229// LLVM: %[[RESULT:.*]] = insertvalue { float, float } poison, float %[[SUB_REAL]], 0230// LLVM: %[[RESULT_2:.*]] = insertvalue { float, float } %[[RESULT]], float %[[SUB_IMAG]], 1231 232// OGCG: %[[A_ADDR:.*]] = alloca { float, float }, align 4233// OGCG: %[[B_ADDR:.*]] = alloca { float, float }, align 4234// OGCG: %[[RESULT:.*]] = alloca { float, float }, align 4235// OGCG: %[[A_REAL_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[A_ADDR]], i32 0, i32 0236// OGCG: %[[A_REAL:.*]] = load float, ptr %[[A_REAL_PTR]], align 4237// OGCG: %[[A_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[A_ADDR]], i32 0, i32 1238// OGCG: %[[A_IMAG:.*]] = load float, ptr %[[A_IMAG_PTR]], align 4239// OGCG: %[[B_REAL_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[B_ADDR]], i32 0, i32 0240// OGCG: %[[B_REAL:.*]] = load float, ptr %[[B_REAL_PTR]], align 4241// OGCG: %[[B_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[B_ADDR]], i32 0, i32 1242// OGCG: %[[B_IMAG:.*]] = load float, ptr %[[B_IMAG_PTR]], align 4243// OGCG: %[[SUB_REAL:.*]] = fsub float %[[A_REAL]], %[[B_REAL]]244// OGCG: %[[SUB_IMAG:.*]] = fsub float %[[A_IMAG]], %[[B_IMAG]]245// OGCG: %[[RESULT_REAL_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[RESULT]], i32 0, i32 0246// OGCG: %[[RESULT_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[RESULT]], i32 0, i32 1247// OGCG: store float %[[SUB_REAL]], ptr %[[RESULT_REAL_PTR]], align 4248// OGCG: store float %[[SUB_IMAG]], ptr %[[RESULT_IMAG_PTR]], align 4249 250void foo6() {251 float _Complex a;252 float _Complex b;253 float _Complex c;254 float _Complex d = (a - b) - c;255}256 257// CIR: %[[A_ADDR:.*]] = cir.alloca !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>, ["a"]258// CIR: %[[B_ADDR:.*]] = cir.alloca !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>, ["b"]259// CIR: %[[C_ADDR:.*]] = cir.alloca !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>, ["c"]260// CIR: %[[RESULT:.*]] = cir.alloca !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>, ["d", init]261// CIR: %[[TMP_A:.*]] = cir.load{{.*}} %[[A_ADDR]] : !cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float>262// CIR: %[[TMP_B:.*]] = cir.load{{.*}} %[[B_ADDR]] : !cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float>263// CIR: %[[SUB_A_B:.*]] = cir.complex.sub %[[TMP_A]], %[[TMP_B]] : !cir.complex<!cir.float>264// CIR: %[[TMP_C:.*]] = cir.load{{.*}} %[[C_ADDR]] : !cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float>265// CIR: %[[SUB_A_B_C:.*]] = cir.complex.sub %[[SUB_A_B]], %[[TMP_C]] : !cir.complex<!cir.float>266// CIR: cir.store{{.*}} %[[SUB_A_B_C]], %[[RESULT]] : !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>267 268// LLVM: %[[A_ADDR:.*]] = alloca { float, float }, i64 1, align 4269// LLVM: %[[B_ADDR:.*]] = alloca { float, float }, i64 1, align 4270// LLVM: %[[C_ADDR:.*]] = alloca { float, float }, i64 1, align 4271// LLVM: %[[RESULT:.*]] = alloca { float, float }, i64 1, align 4272// LLVM: %[[TMP_A:.*]] = load { float, float }, ptr %[[A_ADDR]], align 4273// LLVM: %[[TMP_B:.*]] = load { float, float }, ptr %[[B_ADDR]], align 4274// LLVM: %[[A_REAL:.*]] = extractvalue { float, float } %[[TMP_A]], 0275// LLVM: %[[A_IMAG:.*]] = extractvalue { float, float } %[[TMP_A]], 1276// LLVM: %[[B_REAL:.*]] = extractvalue { float, float } %[[TMP_B]], 0277// LLVM: %[[B_IMAG:.*]] = extractvalue { float, float } %[[TMP_B]], 1278// LLVM: %[[SUB_REAL_A_B:.*]] = fsub float %[[A_REAL]], %[[B_REAL]]279// LLVM: %[[SUB_IMAG_A_B:.*]] = fsub float %[[A_IMAG]], %[[B_IMAG]]280// LLVM: %[[A_B:.*]] = insertvalue { float, float } poison, float %[[SUB_REAL_A_B]], 0281// LLVM: %[[TMP_A_B:.*]] = insertvalue { float, float } %[[A_B]], float %[[SUB_IMAG_A_B]], 1282// LLVM: %[[TMP_C:.*]] = load { float, float }, ptr %[[C_ADDR]], align 4283// LLVM: %[[A_B_REAL:.*]] = extractvalue { float, float } %[[TMP_A_B]], 0284// LLVM: %[[A_B_IMAG:.*]] = extractvalue { float, float } %[[TMP_A_B]], 1285// LLVM: %[[C_REAL:.*]] = extractvalue { float, float } %[[TMP_C]], 0286// LLVM: %[[C_IMAG:.*]] = extractvalue { float, float } %[[TMP_C]], 1287// LLVM: %[[SUB_REAL_A_B_C:.*]] = fsub float %[[A_B_REAL]], %[[C_REAL]]288// LLVM: %[[SUB_IMAG_A_B_C:.*]] = fsub float %[[A_B_IMAG]], %[[C_IMAG]]289// LLVM: %[[A_B_C:.*]] = insertvalue { float, float } poison, float %[[SUB_REAL_A_B_C]], 0290// LLVM: %[[TMP_A_B_C:.*]] = insertvalue { float, float } %[[A_B_C]], float %[[SUB_IMAG_A_B_C]], 1291// LLVM: store { float, float } %[[TMP_A_B_C]], ptr %[[RESULT]], align 4292 293// OGCG: %[[A_ADDR:.*]] = alloca { float, float }, align 4294// OGCG: %[[B_ADDR:.*]] = alloca { float, float }, align 4295// OGCG: %[[C_ADDR:.*]] = alloca { float, float }, align 4296// OGCG: %[[RESULT:.*]] = alloca { float, float }, align 4297// OGCG: %[[A_REAL_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[A_ADDR]], i32 0, i32 0298// OGCG: %[[A_REAL:.*]] = load float, ptr %[[A_REAL_PTR]], align 4299// OGCG: %[[A_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[A_ADDR]], i32 0, i32 1300// OGCG: %[[A_IMAG:.*]] = load float, ptr %[[A_IMAG_PTR]], align 4301// OGCG: %[[B_REAL_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[B_ADDR]], i32 0, i32 0302// OGCG: %[[B_REAL:.*]] = load float, ptr %[[B_REAL_PTR]], align 4303// OGCG: %[[B_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[B_ADDR]], i32 0, i32 1304// OGCG: %[[B_IMAG:.*]] = load float, ptr %[[B_IMAG_PTR]], align 4305// OGCG: %[[SUB_REAL_A_B:.*]] = fsub float %[[A_REAL]], %[[B_REAL]]306// OGCG: %[[SUB_IMAG_A_B:.*]] = fsub float %[[A_IMAG]], %[[B_IMAG]]307// OGCG: %[[C_REAL_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[C_ADDR]], i32 0, i32 0308// OGCG: %[[C_REAL:.*]] = load float, ptr %[[C_REAL_PTR]], align 4309// OGCG: %[[C_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[C_ADDR]], i32 0, i32 1310// OGCG: %[[C_IMAG:.*]] = load float, ptr %[[C_IMAG_PTR]], align 4311// OGCG: %[[SUB_REAL_A_B_C:.*]] = fsub float %[[SUB_REAL_A_B]], %[[C_REAL]]312// OGCG: %[[SUB_IMAG_A_B_C:.*]] = fsub float %[[SUB_IMAG_A_B]], %[[C_IMAG]]313// OGCG: %[[RESULT_REAL_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[RESULT]], i32 0, i32 0314// OGCG: %[[RESULT_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[RESULT]], i32 0, i32 1315// OGCG: store float %[[SUB_REAL_A_B_C]], ptr %[[RESULT_REAL_PTR]], align 4316// OGCG: store float %[[SUB_IMAG_A_B_C]], ptr %[[RESULT_IMAG_PTR]], align 4317 318