brintos

brintos / llvm-project-archived public Read only

0
0
Text · 14.9 KiB · eac0dfa Raw
320 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 a;10  int b = 1 ?: a;11}12 13// CIR: %[[A_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["a"]14// CIR: %[[B_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["b", init]15// CIR: %[[CONST_1:.*]] = cir.const #cir.int<1> : !s32i16// CIR: cir.store{{.*}} %[[CONST_1]], %[[B_ADDR]] : !s32i, !cir.ptr<!s32i>17 18// LLVM: %[[A_ADDR:.*]] = alloca i32, i64 1, align 419// LLVM: %[[B_ADDR:.*]] = alloca i32, i64 1, align 420// LLVM: store i32 1, ptr %[[B_ADDR]], align 421 22// OGCG: %[[A_ADDR:.*]] = alloca i32, align 423// OGCG: %[[B_ADDR:.*]] = alloca i32, align 424// OGCG: store i32 1, ptr %[[B_ADDR]], align 425 26void foo2() {27  float _Complex a;28  float _Complex b;29  float _Complex c = a ?: b;30}31 32// CIR: %[[A_ADDR:.*]] = cir.alloca !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>, ["a"]33// CIR: %[[B_ADDR:.*]] = cir.alloca !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>, ["b"]34// CIR: %[[C_ADDR:.*]] = cir.alloca !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>, ["c", init]35// CIR: %[[TMP_A:.*]] = cir.load{{.*}} %[[A_ADDR]] : !cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float>36// CIR: %[[A_REAL:.*]] = cir.complex.real %[[TMP_A]] : !cir.complex<!cir.float> -> !cir.float37// CIR: %[[A_IMAG:.*]] = cir.complex.imag %[[TMP_A]] : !cir.complex<!cir.float> -> !cir.float38// CIR: %[[A_REAL_BOOL:.*]] = cir.cast float_to_bool %[[A_REAL]] : !cir.float -> !cir.bool39// CIR: %[[A_IMAG_BOOL:.*]] = cir.cast float_to_bool %[[A_IMAG]] : !cir.float -> !cir.bool40// CIR: %[[CONST_TRUE:.*]] = cir.const #true41// CIR: %[[COND:.*]] = cir.select if %[[A_REAL_BOOL]] then %[[CONST_TRUE]] else %[[A_IMAG_BOOL]] : (!cir.bool, !cir.bool, !cir.bool) -> !cir.bool42// CIR: %[[RESULT:.*]] = cir.ternary(%[[COND]], true {43// CIR:   %[[TMP_A:.*]] = cir.load{{.*}} %[[A_ADDR]] : !cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float>44// CIR:   cir.yield %[[TMP_A]] : !cir.complex<!cir.float>45// CIR: }, false {46// CIR:   %[[TMP_B:.*]] = cir.load{{.*}} %[[B_ADDR]] : !cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float>47// CIR:   cir.yield %[[TMP_B]] : !cir.complex<!cir.float>48// CIR: }) : (!cir.bool) -> !cir.complex<!cir.float>49// CIR: cir.store{{.*}} %[[RESULT]], %[[C_ADDR]] : !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>50 51// LLVM: %[[A_ADDR:.*]] = alloca { float, float }, i64 1, align 452// LLVM: %[[B_ADDR:.*]] = alloca { float, float }, i64 1, align 453// LLVM: %[[C_ADDR:.*]] = alloca { float, float }, i64 1, align 454// LLVM: %[[TMP_A:.*]] = load { float, float }, ptr %[[A_ADDR]], align 455// LLVM: %[[A_REAL:.*]] = extractvalue { float, float } %[[TMP_A]], 056// LLVM: %[[A_IMAG:.*]] = extractvalue { float, float } %[[TMP_A]], 157// LLVM: %[[A_REAL_BOOL:.*]] = fcmp une float %[[A_REAL]], 0.000000e+0058// LLVM: %[[A_IMAG_BOOL:.*]] = fcmp une float %[[A_IMAG]], 0.000000e+0059// LLVM: %[[COND:.*]] = or i1 %[[A_REAL_BOOL]], %[[A_IMAG_BOOL]]60// LLVM: br i1 %[[COND]], label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]]61// LLVM: [[COND_TRUE]]:62// LLVM:  %[[TMP_A:.*]] = load { float, float }, ptr %[[A_ADDR]], align 463// LLVM:  br label %[[COND_RESULT:.*]]64// LLVM: [[COND_FALSE]]:65// LLVM:  %[[TMP_B:.*]] = load { float, float }, ptr %[[B_ADDR]], align 466// LLVM:  br label %[[COND_RESULT]]67// LLVM: [[COND_RESULT]]:68// LLVM:  %[[RESULT:.*]] = phi { float, float } [ %[[TMP_B]], %[[COND_FALSE]] ], [ %[[TMP_A]], %[[COND_TRUE]] ]69// LLVM:  br label %[[COND_END:.*]]70// LLVM: [[COND_END]]:71// LLVM:  store { float, float } %[[RESULT]], ptr %[[C_ADDR]], align 472 73// OGCG: %[[A_ADDR:.*]] = alloca { float, float }, align 474// OGCG: %[[B_ADDR:.*]] = alloca { float, float }, align 475// OGCG: %[[C_ADDR:.*]] = alloca { float, float }, align 476// OGCG: %[[A_REAL_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[A_ADDR]], i32 0, i32 077// OGCG: %[[A_REAL:.*]] = load float, ptr %[[A_REAL_PTR]], align 478// OGCG: %[[A_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[A_ADDR]], i32 0, i32 179// OGCG: %[[A_IMAG:.*]] = load float, ptr %[[A_IMAG_PTR]], align 480// OGCG: %[[A_REAL_BOOL:.*]] = fcmp une float %[[A_REAL]], 0.000000e+0081// OGCG: %[[A_IMAG_BOOL:.*]] = fcmp une float %[[A_IMAG]], 0.000000e+0082// OGCG: %[[COND:.*]] = or i1 %[[A_REAL_BOOL]], %[[A_IMAG_BOOL]]83// OGCG: br i1 %tobool2, label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]]84// OGCG: [[COND_TRUE]]:85// OGCG:  %[[A_REAL_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[A_ADDR]], i32 0, i32 086// OGCG:  %[[A_REAL:.*]] = load float, ptr %[[A_REAL_PTR]], align 487// OGCG:  %[[A_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[A_ADDR]], i32 0, i32 188// OGCG:  %[[A_IMAG:.*]] = load float, ptr %[[A_IMAG_PTR]], align 489// OGCG:  br label %[[COND_END:.*]]90// OGCG: [[COND_FALSE]]:91// OGCG:  %[[B_REAL_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[B_ADDR]], i32 0, i32 092// OGCG:  %[[B_REAL:.*]] = load float, ptr %[[B_REAL_PTR]], align 493// OGCG:  %[[B_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[B_ADDR]], i32 0, i32 194// OGCG:  %[[B_IMAG:.*]] = load float, ptr %[[B_IMAG_PTR]], align 495// OGCG:  br label %[[COND_END]]96// OGCG: [[COND_END]]:97// OGCG:  %[[RESULT_REAL:.*]] = phi float [ %[[A_REAL]], %[[COND_TRUE]] ], [ %[[B_REAL]], %[[COND_FALSE]] ]98// OGCG:  %[[RESULT_IMAG:.*]] = phi float [ %[[A_IMAG]], %[[COND_TRUE]] ], [ %[[B_IMAG]], %[[COND_FALSE]] ]99// OGCG:  %[[C_REAL_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[C_ADDR]], i32 0, i32 0100// OGCG:  %[[C_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[C_ADDR]], i32 0, i32 1101// OGCG:  store float %[[RESULT_REAL]], ptr %[[C_REAL_PTR]], align 4102// OGCG:  store float %[[RESULT_IMAG]], ptr %[[C_IMAG_PTR]], align 4103 104void foo3() {105  int a;106  int b;107  int c = a ?: b;108}109 110// CIR: %[[A_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["a"]111// CIR: %[[B_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["b"]112// CIR: %[[C_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["c", init]113// CIR: %[[TMP_A:.*]] = cir.load{{.*}} %[[A_ADDR]] : !cir.ptr<!s32i>, !s32i114// CIR: %[[A_BOOL:.*]] = cir.cast int_to_bool %[[TMP_A]] : !s32i -> !cir.bool115// CIR: %[[RESULT:.*]] = cir.ternary(%[[A_BOOL]], true {116// CIR:   %[[TMP_A:.*]] = cir.load{{.*}} %[[A_ADDR]] : !cir.ptr<!s32i>, !s32i117// CIR:   cir.yield %[[TMP_A]] : !s32i118// CIR: }, false {119// CIR:   %[[TMP_B:.*]] = cir.load{{.*}} %[[B_ADDR]] : !cir.ptr<!s32i>, !s32i120// CIR:   cir.yield %[[TMP_B]] : !s32i121// CIR: }) : (!cir.bool) -> !s32i122// CIR: cir.store{{.*}} %[[RESULT]], %[[C_ADDR]] : !s32i, !cir.ptr<!s32i>123 124// LLVM: %[[A_ADDR:.*]] = alloca i32, i64 1, align 4125// LLVM: %[[B_ADDR:.*]] = alloca i32, i64 1, align 4126// LLVM: %[[C_ADDR:.*]] = alloca i32, i64 1, align 4127// LLVM: %[[TMP_A:.*]] = load i32, ptr %[[A_ADDR]], align 4128// LLVM: %[[COND:.*]] = icmp ne i32 %[[TMP_A]], 0129// LLVM: br i1 %[[COND]], label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]]130// LLVM: [[COND_TRUE]]:131// LLVM:  %[[TMP_A:.*]] = load i32, ptr %[[A_ADDR]], align 4132// LLVM:  br label %[[COND_RESULT:.*]]133// LLVM: [[COND_FALSE]]:134// LLVM:  %[[TMP_B:.*]] = load i32, ptr %[[B_ADDR]], align 4135// LLVM:  br label %[[COND_RESULT]]136// LLVM: [[COND_RESULT]]:137// LLVM:  %[[RESULT:.*]] = phi i32 [ %[[TMP_B]], %[[COND_FALSE]] ], [ %[[TMP_A]], %[[COND_TRUE]] ]138// LLVM:  br label %[[COND_END:.*]]139// LLVM: [[COND_END]]:140// LLVM:  store i32 %[[RESULT]], ptr %[[C_ADDR]], align 4141 142// OGCG: %[[A_ADDR:.*]] = alloca i32, align 4143// OGCG: %[[B_ADDR:.*]] = alloca i32, align 4144// OGCG: %[[C_ADDR:.*]] = alloca i32, align 4145// OGCG: %[[TMP_A:.*]] = load i32, ptr %[[A_ADDR]], align 4146// OGCG: %[[A_BOOL:.*]] = icmp ne i32 %[[TMP_A]], 0147// OGCG: br i1 %[[A_BOOL]], label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]]148// OGCG: [[COND_TRUE]]:149// OGCG:  %[[TMP_A:.*]] = load i32, ptr %[[A_ADDR]], align 4150// OGCG:  br label %[[COND_END:.*]]151// OGCG: [[COND_FALSE]]:152// OGCG:  %[[TMP_B:.*]] = load i32, ptr %[[B_ADDR]], align 4153// OGCG:  br label %[[COND_END]]154// OGCG: [[COND_END]]:155// OGCG:  %[[RESULT:.*]] = phi i32 [ %[[TMP_A]], %[[COND_TRUE]] ], [ %[[TMP_B]], %[[COND_FALSE]] ]156// OGCG:  store i32 %[[RESULT]], ptr %[[C_ADDR]], align 4157 158void test_gnu_binary_lvalue_assign() {159  int a = 5;160  int b = 10;161  (a ?: b) = 42;162}163 164// CIR-LABEL: cir.func{{.*}} @_Z29test_gnu_binary_lvalue_assignv(165// CIR: %[[A:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["a", init]166// CIR: %[[B:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["b", init]167// CIR: %[[A_VAL:.*]] = cir.load{{.*}} %[[A]] : !cir.ptr<!s32i>, !s32i168// CIR: %[[A_BOOL:.*]] = cir.cast int_to_bool %[[A_VAL]] : !s32i -> !cir.bool169// CIR: %[[TERNARY_PTR:.*]] = cir.ternary(%[[A_BOOL]], true {170// CIR:   cir.yield %[[A]] : !cir.ptr<!s32i>171// CIR: }, false {172// CIR:   cir.yield %[[B]] : !cir.ptr<!s32i>173// CIR: }) : (!cir.bool) -> !cir.ptr<!s32i>174// CIR: cir.store{{.*}} %{{.*}}, %[[TERNARY_PTR]] : !s32i, !cir.ptr<!s32i>175 176// LLVM-LABEL: define{{.*}} void @_Z29test_gnu_binary_lvalue_assignv(177// LLVM: %[[A:.*]] = alloca i32178// LLVM: %[[B:.*]] = alloca i32179// LLVM: %[[A_VAL:.*]] = load i32, ptr %[[A]]180// LLVM: %[[COND:.*]] = icmp ne i32 %[[A_VAL]], 0181// LLVM: br i1 %[[COND]], label %[[TRUE_BB:.*]], label %[[FALSE_BB:.*]]182// LLVM: [[TRUE_BB]]:183// LLVM:   br label %[[MERGE_BB:.*]]184// LLVM: [[FALSE_BB]]:185// LLVM:   br label %[[MERGE_BB]]186// LLVM: [[MERGE_BB]]:187// LLVM:   %[[PHI_PTR:.*]] = phi ptr [ %[[B]], %[[FALSE_BB]] ], [ %[[A]], %[[TRUE_BB]] ]188// LLVM:   br label %[[CONT_BB:.*]]189// LLVM: [[CONT_BB]]:190// LLVM:   store i32 42, ptr %[[PHI_PTR]]191 192// OGCG-LABEL: define{{.*}} void @_Z29test_gnu_binary_lvalue_assignv(193// OGCG: %[[A:.*]] = alloca i32194// OGCG: %[[B:.*]] = alloca i32195// OGCG: %[[A_VAL:.*]] = load i32, ptr %[[A]]196// OGCG: %[[COND:.*]] = icmp ne i32 %[[A_VAL]], 0197// OGCG: br i1 %[[COND]], label %[[TRUE_BB:.*]], label %[[FALSE_BB:.*]]198// OGCG: [[TRUE_BB]]:199// OGCG:   br label %[[MERGE_BB:.*]]200// OGCG: [[FALSE_BB]]:201// OGCG:   br label %[[MERGE_BB]]202// OGCG: [[MERGE_BB]]:203// OGCG:   %[[PHI_PTR:.*]] = phi ptr [ %[[A]], %[[TRUE_BB]] ], [ %[[B]], %[[FALSE_BB]] ]204// OGCG:   store i32 42, ptr %[[PHI_PTR]]205 206void test_gnu_binary_lvalue_compound() {207  int a = 7;208  int b = 14;209  (a ?: b) += 5;210}211 212// CIR-LABEL: cir.func{{.*}} @_Z31test_gnu_binary_lvalue_compoundv(213// CIR: %[[A:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["a", init]214// CIR: %[[B:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["b", init]215// CIR: %[[A_VAL:.*]] = cir.load{{.*}} %[[A]] : !cir.ptr<!s32i>, !s32i216// CIR: %[[A_BOOL:.*]] = cir.cast int_to_bool %[[A_VAL]] : !s32i -> !cir.bool217// CIR: %[[LVAL_PTR:.*]] = cir.ternary(%[[A_BOOL]], true {218// CIR:   cir.yield %[[A]] : !cir.ptr<!s32i>219// CIR: }, false {220// CIR:   cir.yield %[[B]] : !cir.ptr<!s32i>221// CIR: }) : (!cir.bool) -> !cir.ptr<!s32i>222// CIR: %[[OLD_VAL:.*]] = cir.load{{.*}} %[[LVAL_PTR]]223// CIR: %[[NEW_VAL:.*]] = cir.binop(add, %[[OLD_VAL]], %{{.*}})224// CIR: cir.store{{.*}} %[[NEW_VAL]], %[[LVAL_PTR]]225 226// LLVM-LABEL: define{{.*}} void @_Z31test_gnu_binary_lvalue_compoundv(227// LLVM: %[[A:.*]] = alloca i32228// LLVM: %[[B:.*]] = alloca i32229// LLVM: %[[A_VAL:.*]] = load i32, ptr %[[A]]230// LLVM: %[[COND:.*]] = icmp ne i32 %[[A_VAL]], 0231// LLVM: br i1 %[[COND]], label %[[TRUE_BB:.*]], label %[[FALSE_BB:.*]]232// LLVM: [[TRUE_BB]]:233// LLVM:   br label %[[MERGE_BB:.*]]234// LLVM: [[FALSE_BB]]:235// LLVM:   br label %[[MERGE_BB]]236// LLVM: [[MERGE_BB]]:237// LLVM:   %[[PTR:.*]] = phi ptr [ %[[B]], %[[FALSE_BB]] ], [ %[[A]], %[[TRUE_BB]] ]238// LLVM:   br label %[[CONT:.*]]239// LLVM: [[CONT]]:240// LLVM:   %[[OLD:.*]] = load i32, ptr %[[PTR]]241// LLVM:   %[[NEW:.*]] = add{{.*}} i32 %[[OLD]], 5242// LLVM:   store i32 %[[NEW]], ptr %[[PTR]]243 244// OGCG-LABEL: define{{.*}} void @_Z31test_gnu_binary_lvalue_compoundv(245// OGCG: %[[A:.*]] = alloca i32246// OGCG: %[[B:.*]] = alloca i32247// OGCG: %[[A_VAL:.*]] = load i32, ptr %[[A]]248// OGCG: %[[COND:.*]] = icmp ne i32 %[[A_VAL]], 0249// OGCG: br i1 %[[COND]], label %[[TRUE_BB:.*]], label %[[FALSE_BB:.*]]250// OGCG: [[TRUE_BB]]:251// OGCG:   br label %[[MERGE_BB:.*]]252// OGCG: [[FALSE_BB]]:253// OGCG:   br label %[[MERGE_BB]]254// OGCG: [[MERGE_BB]]:255// OGCG:   %[[PTR:.*]] = phi ptr [ %[[A]], %[[TRUE_BB]] ], [ %[[B]], %[[FALSE_BB]] ]256// OGCG:   %[[OLD:.*]] = load i32, ptr %[[PTR]]257// OGCG:   %[[NEW:.*]] = add{{.*}} i32 %[[OLD]], 5258// OGCG:   store i32 %[[NEW]], ptr %[[PTR]]259 260void test_gnu_binary_lvalue_ptr() {261  int x = 1, y = 2;262  int *p = &x;263  int *q = nullptr;264  *(p ?: q) = 99;265}266 267// CIR-LABEL: cir.func{{.*}} @_Z26test_gnu_binary_lvalue_ptrv(268// CIR: %[[X:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["x", init]269// CIR: %[[Y:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["y", init]270// CIR: %[[P:.*]] = cir.alloca !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>, ["p", init]271// CIR: %[[Q:.*]] = cir.alloca !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>, ["q", init]272// CIR: %[[P_VAL:.*]] = cir.load{{.*}} %[[P]]273// CIR: %[[P_BOOL:.*]] = cir.cast ptr_to_bool %[[P_VAL]]274// CIR: %[[PTR_RESULT:.*]] = cir.ternary(%[[P_BOOL]], true {275// CIR:   %[[P_LOAD:.*]] = cir.load{{.*}} %[[P]]276// CIR:   cir.yield %[[P_LOAD]] : !cir.ptr<!s32i>277// CIR: }, false {278// CIR:   %[[Q_LOAD:.*]] = cir.load{{.*}} %[[Q]]279// CIR:   cir.yield %[[Q_LOAD]] : !cir.ptr<!s32i>280// CIR: }) : (!cir.bool) -> !cir.ptr<!s32i>281// CIR: cir.store{{.*}} %{{.*}}, %[[PTR_RESULT]]282 283// LLVM-LABEL: define{{.*}} void @_Z26test_gnu_binary_lvalue_ptrv(284// LLVM: %[[X:.*]] = alloca i32285// LLVM: %[[Y:.*]] = alloca i32286// LLVM: %[[P:.*]] = alloca ptr287// LLVM: %[[Q:.*]] = alloca ptr288// LLVM: %[[P_VAL:.*]] = load ptr, ptr %[[P]]289// LLVM: %[[COND:.*]] = icmp ne ptr %[[P_VAL]], null290// LLVM: br i1 %[[COND]], label %[[TRUE_BB:.*]], label %[[FALSE_BB:.*]]291// LLVM: [[TRUE_BB]]:292// LLVM:   %[[P_LOAD:.*]] = load ptr, ptr %[[P]]293// LLVM:   br label %[[MERGE_BB:.*]]294// LLVM: [[FALSE_BB]]:295// LLVM:   %[[Q_LOAD:.*]] = load ptr, ptr %[[Q]]296// LLVM:   br label %[[MERGE_BB]]297// LLVM: [[MERGE_BB]]:298// LLVM:   %[[PHI:.*]] = phi ptr [ %[[Q_LOAD]], %[[FALSE_BB]] ], [ %[[P_LOAD]], %[[TRUE_BB]] ]299// LLVM:   br label %[[CONT:.*]]300// LLVM: [[CONT]]:301// LLVM:   store i32 99, ptr %[[PHI]]302 303// OGCG-LABEL: define{{.*}} void @_Z26test_gnu_binary_lvalue_ptrv(304// OGCG: %[[X:.*]] = alloca i32305// OGCG: %[[Y:.*]] = alloca i32306// OGCG: %[[P:.*]] = alloca ptr307// OGCG: %[[Q:.*]] = alloca ptr308// OGCG: %[[P_VAL:.*]] = load ptr, ptr %[[P]]309// OGCG: %[[COND:.*]] = icmp ne ptr %[[P_VAL]], null310// OGCG: br i1 %[[COND]], label %[[TRUE_BB:.*]], label %[[FALSE_BB:.*]]311// OGCG: [[TRUE_BB]]:312// OGCG:   %[[P_LOAD:.*]] = load ptr, ptr %[[P]]313// OGCG:   br label %[[MERGE_BB:.*]]314// OGCG: [[FALSE_BB]]:315// OGCG:   %[[Q_LOAD:.*]] = load ptr, ptr %[[Q]]316// OGCG:   br label %[[MERGE_BB]]317// OGCG: [[MERGE_BB]]:318// OGCG:   %[[PHI:.*]] = phi ptr [ %[[P_LOAD]], %[[TRUE_BB]] ], [ %[[Q_LOAD]], %[[FALSE_BB]] ]319// OGCG:   store i32 99, ptr %[[PHI]]320