brintos

brintos / llvm-project-archived public Read only

0
0
Text · 16.6 KiB · 706ce4e Raw
507 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -S -passes=instcombine < %s | FileCheck %s3 4declare void @foo()5declare void @bar()6declare void @baz()7declare void @qux()8declare void @quux()9 10declare i1 @geni1()11 12declare void @usei32(i32)13declare void @usei32i32agg({ i32, i32 })14 15; Most basic test - diamond structure16define { i32, i32 } @test0({ i32, i32 } %agg_left, { i32, i32 } %agg_right, i1 %c) {17; CHECK-LABEL: @test0(18; CHECK-NEXT:  entry:19; CHECK-NEXT:    br i1 [[C:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]]20; CHECK:       left:21; CHECK-NEXT:    call void @foo()22; CHECK-NEXT:    br label [[END:%.*]]23; CHECK:       right:24; CHECK-NEXT:    call void @bar()25; CHECK-NEXT:    br label [[END]]26; CHECK:       end:27; CHECK-NEXT:    [[AGG_LEFT_PN:%.*]] = phi { i32, i32 } [ [[AGG_LEFT:%.*]], [[LEFT]] ], [ [[AGG_RIGHT:%.*]], [[RIGHT]] ]28; CHECK-NEXT:    call void @baz()29; CHECK-NEXT:    ret { i32, i32 } [[AGG_LEFT_PN]]30;31entry:32  br i1 %c, label %left, label %right33 34left:35  %i0 = extractvalue { i32, i32 } %agg_left, 036  %i2 = extractvalue { i32, i32 } %agg_left, 137  call void @foo()38  br label %end39 40right:41  %i3 = extractvalue { i32, i32 } %agg_right, 042  %i4 = extractvalue { i32, i32 } %agg_right, 143  call void @bar()44  br label %end45 46end:47  %i5 = phi i32 [ %i0, %left ], [ %i3, %right ]48  %i6 = phi i32 [ %i2, %left ], [ %i4, %right ]49  call void @baz()50  %i7 = insertvalue { i32, i32 } undef, i32 %i5, 051  %i8 = insertvalue { i32, i32 } %i7, i32 %i6, 152  ret { i32, i32 } %i853}54 55; Second element is coming from wrong aggregate56define { i32, i32 } @negative_test1({ i32, i32 } %agg_left, { i32, i32 } %agg_right, i1 %c) {57; CHECK-LABEL: @negative_test1(58; CHECK-NEXT:  entry:59; CHECK-NEXT:    br i1 [[C:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]]60; CHECK:       left:61; CHECK-NEXT:    call void @foo()62; CHECK-NEXT:    br label [[END:%.*]]63; CHECK:       right:64; CHECK-NEXT:    call void @bar()65; CHECK-NEXT:    br label [[END]]66; CHECK:       end:67; CHECK-NEXT:    [[AGG_LEFT_PN:%.*]] = phi { i32, i32 } [ [[AGG_LEFT:%.*]], [[LEFT]] ], [ [[AGG_RIGHT:%.*]], [[RIGHT]] ]68; CHECK-NEXT:    [[AGG_RIGHT_PN:%.*]] = phi { i32, i32 } [ [[AGG_RIGHT]], [[LEFT]] ], [ [[AGG_LEFT]], [[RIGHT]] ]69; CHECK-NEXT:    [[I6:%.*]] = extractvalue { i32, i32 } [[AGG_RIGHT_PN]], 170; CHECK-NEXT:    [[I5:%.*]] = extractvalue { i32, i32 } [[AGG_LEFT_PN]], 071; CHECK-NEXT:    call void @baz()72; CHECK-NEXT:    [[I7:%.*]] = insertvalue { i32, i32 } undef, i32 [[I5]], 073; CHECK-NEXT:    [[I8:%.*]] = insertvalue { i32, i32 } [[I7]], i32 [[I6]], 174; CHECK-NEXT:    ret { i32, i32 } [[I8]]75;76entry:77  %i0 = extractvalue { i32, i32 } %agg_left, 078  %i2 = extractvalue { i32, i32 } %agg_left, 179  %i3 = extractvalue { i32, i32 } %agg_right, 080  %i4 = extractvalue { i32, i32 } %agg_right, 181  br i1 %c, label %left, label %right82 83left:84  call void @foo()85  br label %end86 87right:88  call void @bar()89  br label %end90 91end:92  %i5 = phi i32 [ %i0, %left ], [ %i3, %right ]93  %i6 = phi i32 [ %i4, %left ], [ %i2, %right ]94  call void @baz()95  %i7 = insertvalue { i32, i32 } undef, i32 %i5, 096  %i8 = insertvalue { i32, i32 } %i7, i32 %i6, 197  ret { i32, i32 } %i898}99 100; When coming from %left, elements are swapped, and new insertvalue is created.101; From right side the old aggregate can be directly reused.102define { i32, i32 } @positive_test2({ i32, i32 } %agg_left, { i32, i32 } %agg_right, i1 %c) {103; CHECK-LABEL: @positive_test2(104; CHECK-NEXT:  entry:105; CHECK-NEXT:    br i1 [[C:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]]106; CHECK:       left:107; CHECK-NEXT:    [[I2:%.*]] = extractvalue { i32, i32 } [[AGG_LEFT:%.*]], 1108; CHECK-NEXT:    [[I0:%.*]] = extractvalue { i32, i32 } [[AGG_LEFT]], 0109; CHECK-NEXT:    call void @foo()110; CHECK-NEXT:    [[TMP0:%.*]] = insertvalue { i32, i32 } poison, i32 [[I2]], 0111; CHECK-NEXT:    [[TMP1:%.*]] = insertvalue { i32, i32 } [[TMP0]], i32 [[I0]], 1112; CHECK-NEXT:    br label [[END:%.*]]113; CHECK:       right:114; CHECK-NEXT:    call void @bar()115; CHECK-NEXT:    br label [[END]]116; CHECK:       end:117; CHECK-NEXT:    [[I8_MERGED:%.*]] = phi { i32, i32 } [ [[TMP1]], [[LEFT]] ], [ [[AGG_RIGHT:%.*]], [[RIGHT]] ]118; CHECK-NEXT:    call void @baz()119; CHECK-NEXT:    ret { i32, i32 } [[I8_MERGED]]120;121entry:122  %i0 = extractvalue { i32, i32 } %agg_left, 0123  %i2 = extractvalue { i32, i32 } %agg_left, 1124  %i3 = extractvalue { i32, i32 } %agg_right, 0125  %i4 = extractvalue { i32, i32 } %agg_right, 1126  br i1 %c, label %left, label %right127 128left:129  call void @foo()130  br label %end131 132right:133  call void @bar()134  br label %end135 136end:137  %i5 = phi i32 [ %i2, %left ], [ %i3, %right ]138  %i6 = phi i32 [ %i0, %left ], [ %i4, %right ]139  call void @baz()140  %i7 = insertvalue { i32, i32 } undef, i32 %i5, 0141  %i8 = insertvalue { i32, i32 } %i7, i32 %i6, 1142  ret { i32, i32 } %i8143}144 145; FIXME: we should probably be able to handle multiple levels of PHI indirection146define { i32, i32 } @test3({ i32, i32 } %agg_00, { i32, i32 } %agg_01, { i32, i32 } %agg_10, i1 %c0, i1 %c1) {147; CHECK-LABEL: @test3(148; CHECK-NEXT:  entry:149; CHECK-NEXT:    br i1 [[C0:%.*]], label [[BB0_DISPATCH:%.*]], label [[BB10:%.*]]150; CHECK:       bb0.dispatch:151; CHECK-NEXT:    br i1 [[C1:%.*]], label [[BB00:%.*]], label [[BB01:%.*]]152; CHECK:       bb00:153; CHECK-NEXT:    br label [[BB0_MERGE:%.*]]154; CHECK:       bb01:155; CHECK-NEXT:    br label [[BB0_MERGE]]156; CHECK:       bb0.merge:157; CHECK-NEXT:    [[AGG_00_PN:%.*]] = phi { i32, i32 } [ [[AGG_00:%.*]], [[BB00]] ], [ [[AGG_01:%.*]], [[BB01]] ]158; CHECK-NEXT:    br label [[END:%.*]]159; CHECK:       bb10:160; CHECK-NEXT:    br label [[END]]161; CHECK:       end:162; CHECK-NEXT:    [[AGG_00_PN_PN:%.*]] = phi { i32, i32 } [ [[AGG_00_PN]], [[BB0_MERGE]] ], [ [[AGG_10:%.*]], [[BB10]] ]163; CHECK-NEXT:    call void @baz()164; CHECK-NEXT:    ret { i32, i32 } [[AGG_00_PN_PN]]165;166entry:167  br i1 %c0, label %bb0.dispatch, label %bb10168 169bb0.dispatch:170  br i1 %c1, label %bb00, label %bb01171 172bb00:173  %i0 = extractvalue { i32, i32 } %agg_00, 0174  %i1 = extractvalue { i32, i32 } %agg_00, 1175  br label %bb0.merge176 177bb01:178  %i2 = extractvalue { i32, i32 } %agg_01, 0179  %i3 = extractvalue { i32, i32 } %agg_01, 1180  br label %bb0.merge181 182bb0.merge:183  %i4 = phi i32 [ %i0, %bb00 ], [ %i2, %bb01 ]184  %i5 = phi i32 [ %i1, %bb00 ], [ %i3, %bb01 ]185  br label %end186 187bb10:188  %i6 = extractvalue { i32, i32 } %agg_10, 0189  %i7 = extractvalue { i32, i32 } %agg_10, 1190  br label %end191 192end:193  %i8 = phi i32 [ %i4, %bb0.merge ], [ %i6, %bb10 ]194  %i9 = phi i32 [ %i5, %bb0.merge ], [ %i7, %bb10 ]195  call void @baz()196  %i10 = insertvalue { i32, i32 } undef, i32 %i8, 0197  %i11 = insertvalue { i32, i32 } %i10, i32 %i9, 1198  ret { i32, i32 } %i11199}200 201; Not sure what should happen for cycles.202define { i32, i32 } @test4({ i32, i32 } %agg_left, { i32, i32 } %agg_right, i1 %c0) {203; CHECK-LABEL: @test4(204; CHECK-NEXT:  entry:205; CHECK-NEXT:    br i1 [[C0:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]]206; CHECK:       left:207; CHECK-NEXT:    [[I0:%.*]] = extractvalue { i32, i32 } [[AGG_LEFT:%.*]], 0208; CHECK-NEXT:    [[I2:%.*]] = extractvalue { i32, i32 } [[AGG_LEFT]], 1209; CHECK-NEXT:    call void @foo()210; CHECK-NEXT:    br label [[MIDDLE:%.*]]211; CHECK:       right:212; CHECK-NEXT:    [[I3:%.*]] = extractvalue { i32, i32 } [[AGG_RIGHT:%.*]], 0213; CHECK-NEXT:    [[I4:%.*]] = extractvalue { i32, i32 } [[AGG_RIGHT]], 1214; CHECK-NEXT:    call void @bar()215; CHECK-NEXT:    br label [[MIDDLE]]216; CHECK:       middle:217; CHECK-NEXT:    [[I5:%.*]] = phi i32 [ [[I0]], [[LEFT]] ], [ [[I3]], [[RIGHT]] ], [ [[I5]], [[MIDDLE]] ]218; CHECK-NEXT:    [[I6:%.*]] = phi i32 [ [[I2]], [[LEFT]] ], [ [[I4]], [[RIGHT]] ], [ [[I6]], [[MIDDLE]] ]219; CHECK-NEXT:    call void @baz()220; CHECK-NEXT:    [[C1:%.*]] = call i1 @geni1()221; CHECK-NEXT:    br i1 [[C1]], label [[END:%.*]], label [[MIDDLE]]222; CHECK:       end:223; CHECK-NEXT:    [[I7:%.*]] = insertvalue { i32, i32 } undef, i32 [[I5]], 0224; CHECK-NEXT:    [[I8:%.*]] = insertvalue { i32, i32 } [[I7]], i32 [[I6]], 1225; CHECK-NEXT:    ret { i32, i32 } [[I8]]226;227entry:228  br i1 %c0, label %left, label %right229 230left:231  %i0 = extractvalue { i32, i32 } %agg_left, 0232  %i2 = extractvalue { i32, i32 } %agg_left, 1233  call void @foo()234  br label %middle235 236right:237  %i3 = extractvalue { i32, i32 } %agg_right, 0238  %i4 = extractvalue { i32, i32 } %agg_right, 1239  call void @bar()240  br label %middle241 242middle:243  %i5 = phi i32 [ %i0, %left ], [ %i3, %right ], [ %i5, %middle ]244  %i6 = phi i32 [ %i2, %left ], [ %i4, %right ], [ %i6, %middle ]245  call void @baz()246  %i7 = insertvalue { i32, i32 } undef, i32 %i5, 0247  %i8 = insertvalue { i32, i32 } %i7, i32 %i6, 1248  %c1 = call i1 @geni1()249  br i1 %c1, label %end, label %middle250 251end:252  ret { i32, i32 } %i8253}254 255; But here since we start without an explicit self-cycle, we already manage to fold it.256define { i32, i32 } @test5({ i32, i32 } %agg_left, { i32, i32 } %agg_right, i1 %c0) {257; CHECK-LABEL: @test5(258; CHECK-NEXT:  entry:259; CHECK-NEXT:    br i1 [[C0:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]]260; CHECK:       left:261; CHECK-NEXT:    call void @foo()262; CHECK-NEXT:    br label [[MIDDLE:%.*]]263; CHECK:       right:264; CHECK-NEXT:    call void @bar()265; CHECK-NEXT:    br label [[MIDDLE]]266; CHECK:       middle:267; CHECK-NEXT:    [[AGG_LEFT_PN:%.*]] = phi { i32, i32 } [ [[AGG_LEFT:%.*]], [[LEFT]] ], [ [[AGG_RIGHT:%.*]], [[RIGHT]] ], [ [[AGG_LEFT_PN]], [[MIDDLE]] ]268; CHECK-NEXT:    call void @baz()269; CHECK-NEXT:    [[C1:%.*]] = call i1 @geni1()270; CHECK-NEXT:    br i1 [[C1]], label [[END:%.*]], label [[MIDDLE]]271; CHECK:       end:272; CHECK-NEXT:    ret { i32, i32 } [[AGG_LEFT_PN]]273;274entry:275  br i1 %c0, label %left, label %right276 277left:278  %i0 = extractvalue { i32, i32 } %agg_left, 0279  %i2 = extractvalue { i32, i32 } %agg_left, 1280  call void @foo()281  br label %middle282 283right:284  %i3 = extractvalue { i32, i32 } %agg_right, 0285  %i4 = extractvalue { i32, i32 } %agg_right, 1286  call void @bar()287  br label %middle288 289middle:290  %i5 = phi i32 [ %i0, %left ], [ %i3, %right ], [ %i9, %middle ]291  %i6 = phi i32 [ %i2, %left ], [ %i4, %right ], [ %i10, %middle ]292  call void @baz()293  %i7 = insertvalue { i32, i32 } undef, i32 %i5, 0294  %i8 = insertvalue { i32, i32 } %i7, i32 %i6, 1295  %i9 = extractvalue { i32, i32 } %i8, 0296  %i10 = extractvalue { i32, i32 } %i8, 1297  %c1 = call i1 @geni1()298  br i1 %c1, label %end, label %middle299 300end:301  ret { i32, i32 } %i8302}303 304; Diamond structure, but with "padding" block before the use.305define { i32, i32 } @test6({ i32, i32 } %agg_left, { i32, i32 } %agg_right, i1 %c0, i1 %c1) {306; CHECK-LABEL: @test6(307; CHECK-NEXT:  entry:308; CHECK-NEXT:    br i1 [[C0:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]]309; CHECK:       left:310; CHECK-NEXT:    call void @foo()311; CHECK-NEXT:    br label [[MERGE:%.*]]312; CHECK:       right:313; CHECK-NEXT:    call void @bar()314; CHECK-NEXT:    br label [[MERGE]]315; CHECK:       merge:316; CHECK-NEXT:    [[AGG_LEFT_PN:%.*]] = phi { i32, i32 } [ [[AGG_LEFT:%.*]], [[LEFT]] ], [ [[AGG_RIGHT:%.*]], [[RIGHT]] ]317; CHECK-NEXT:    call void @baz()318; CHECK-NEXT:    br i1 [[C1:%.*]], label [[END:%.*]], label [[PASSTHROUGH:%.*]]319; CHECK:       passthrough:320; CHECK-NEXT:    call void @qux()321; CHECK-NEXT:    br label [[END]]322; CHECK:       end:323; CHECK-NEXT:    call void @quux()324; CHECK-NEXT:    ret { i32, i32 } [[AGG_LEFT_PN]]325;326entry:327  br i1 %c0, label %left, label %right328 329left:330  %i0 = extractvalue { i32, i32 } %agg_left, 0331  %i2 = extractvalue { i32, i32 } %agg_left, 1332  call void @foo()333  br label %merge334 335right:336  %i3 = extractvalue { i32, i32 } %agg_right, 0337  %i4 = extractvalue { i32, i32 } %agg_right, 1338  call void @bar()339  br label %merge340 341merge:342  %i5 = phi i32 [ %i0, %left ], [ %i3, %right ]343  %i6 = phi i32 [ %i2, %left ], [ %i4, %right ]344  call void @baz()345  br i1 %c1, label %end, label %passthrough346 347passthrough:348  call void @qux()349  br label %end350 351end:352  call void @quux()353  %i7 = insertvalue { i32, i32 } undef, i32 %i5, 0354  %i8 = insertvalue { i32, i32 } %i7, i32 %i6, 1355  ret { i32, i32 } %i8356}357 358; All the definitions of the aggregate elements must happen in the same block.359define { i32, i32 } @negative_test7({ i32, i32 } %agg_left, { i32, i32 } %agg_right, i1 %c0, i1 %c1) {360; CHECK-LABEL: @negative_test7(361; CHECK-NEXT:  entry:362; CHECK-NEXT:    [[I0:%.*]] = extractvalue { i32, i32 } [[AGG_LEFT:%.*]], 0363; CHECK-NEXT:    call void @usei32(i32 [[I0]])364; CHECK-NEXT:    br i1 [[C0:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]]365; CHECK:       left:366; CHECK-NEXT:    [[I1:%.*]] = extractvalue { i32, i32 } [[AGG_LEFT]], 1367; CHECK-NEXT:    call void @usei32(i32 [[I1]])368; CHECK-NEXT:    br label [[MERGE:%.*]]369; CHECK:       right:370; CHECK-NEXT:    [[I2:%.*]] = extractvalue { i32, i32 } [[AGG_RIGHT:%.*]], 1371; CHECK-NEXT:    call void @usei32(i32 [[I2]])372; CHECK-NEXT:    br label [[MERGE]]373; CHECK:       merge:374; CHECK-NEXT:    [[I3:%.*]] = phi i32 [ [[I1]], [[LEFT]] ], [ [[I2]], [[RIGHT]] ]375; CHECK-NEXT:    call void @bar()376; CHECK-NEXT:    br label [[END:%.*]]377; CHECK:       end:378; CHECK-NEXT:    call void @baz()379; CHECK-NEXT:    [[I7:%.*]] = insertvalue { i32, i32 } undef, i32 [[I0]], 0380; CHECK-NEXT:    [[I8:%.*]] = insertvalue { i32, i32 } [[I7]], i32 [[I3]], 1381; CHECK-NEXT:    ret { i32, i32 } [[I8]]382;383entry:384  %i0 = extractvalue { i32, i32 } %agg_left, 0385  call void @usei32(i32 %i0)386  br i1 %c0, label %left, label %right387 388left:389  %i1 = extractvalue { i32, i32 } %agg_left, 1390  call void @usei32(i32 %i1)391  br label %merge392 393right:394  %i2 = extractvalue { i32, i32 } %agg_right, 1395  call void @usei32(i32 %i2)396  br label %merge397 398merge:399  %i3 = phi i32 [ %i1, %left ], [ %i2, %right ]400  call void @bar()401  br label %end402 403end:404  call void @baz()405  %i7 = insertvalue { i32, i32 } undef, i32 %i0, 0406  %i8 = insertvalue { i32, i32 } %i7, i32 %i3, 1407  ret { i32, i32 } %i8408}409 410; Most basic test - diamond structure, but with a switch, which results in multiple duplicate predecessors411define { i32, i32 } @test8({ i32, i32 } %agg_left, { i32, i32 } %agg_right, i1 %c, i32 %val_left, i32 %val_right) {412; CHECK-LABEL: @test8(413; CHECK-NEXT:  entry:414; CHECK-NEXT:    br i1 [[C:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]]415; CHECK:       left:416; CHECK-NEXT:    call void @foo()417; CHECK-NEXT:    switch i32 [[VAL_LEFT:%.*]], label [[IMPOSSIBLE:%.*]] [418; CHECK-NEXT:      i32 -42, label [[END:%.*]]419; CHECK-NEXT:      i32 42, label [[END]]420; CHECK-NEXT:    ]421; CHECK:       right:422; CHECK-NEXT:    call void @bar()423; CHECK-NEXT:    switch i32 [[VAL_RIGHT:%.*]], label [[IMPOSSIBLE]] [424; CHECK-NEXT:      i32 42, label [[END]]425; CHECK-NEXT:      i32 -42, label [[END]]426; CHECK-NEXT:    ]427; CHECK:       impossible:428; CHECK-NEXT:    unreachable429; CHECK:       end:430; CHECK-NEXT:    [[AGG_LEFT_PN:%.*]] = phi { i32, i32 } [ [[AGG_LEFT:%.*]], [[LEFT]] ], [ [[AGG_LEFT]], [[LEFT]] ], [ [[AGG_RIGHT:%.*]], [[RIGHT]] ], [ [[AGG_RIGHT]], [[RIGHT]] ]431; CHECK-NEXT:    call void @baz()432; CHECK-NEXT:    ret { i32, i32 } [[AGG_LEFT_PN]]433;434entry:435  br i1 %c, label %left, label %right436 437left:438  %i0 = extractvalue { i32, i32 } %agg_left, 0439  %i2 = extractvalue { i32, i32 } %agg_left, 1440  call void @foo()441  switch i32 %val_left, label %impossible [442  i32 -42, label %end443  i32 42, label %end444  ]445 446right:447  %i3 = extractvalue { i32, i32 } %agg_right, 0448  %i4 = extractvalue { i32, i32 } %agg_right, 1449  call void @bar()450  switch i32 %val_right, label %impossible [451  i32 42, label %end452  i32 -42, label %end453  ]454 455impossible:456  unreachable457 458end:459  %i5 = phi i32 [ %i0, %left ], [ %i0, %left ], [ %i3, %right ], [ %i3, %right ]460  %i6 = phi i32 [ %i2, %left ], [ %i2, %left ], [ %i4, %right ], [ %i4, %right ]461  call void @baz()462  %i7 = insertvalue { i32, i32 } undef, i32 %i5, 0463  %i8 = insertvalue { i32, i32 } %i7, i32 %i6, 1464  ret { i32, i32 } %i8465}466 467; The insertion of first element could have been split/hoisted into the predecessors.468define { i32, i32 } @test9({ i32, i32 } %agg_left, { i32, i32 } %agg_right, i1 %c) {469; CHECK-LABEL: @test9(470; CHECK-NEXT:  entry:471; CHECK-NEXT:    br i1 [[C:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]]472; CHECK:       left:473; CHECK-NEXT:    call void @foo()474; CHECK-NEXT:    br label [[END:%.*]]475; CHECK:       right:476; CHECK-NEXT:    call void @bar()477; CHECK-NEXT:    br label [[END]]478; CHECK:       end:479; CHECK-NEXT:    [[AGG_LEFT_PN:%.*]] = phi { i32, i32 } [ [[AGG_LEFT:%.*]], [[LEFT]] ], [ [[AGG_RIGHT:%.*]], [[RIGHT]] ]480; CHECK-NEXT:    call void @baz()481; CHECK-NEXT:    ret { i32, i32 } [[AGG_LEFT_PN]]482;483entry:484  br i1 %c, label %left, label %right485 486left:487  %i0 = extractvalue { i32, i32 } %agg_left, 0488  %i1 = extractvalue { i32, i32 } %agg_left, 1489  %i2 = insertvalue { i32, i32 } undef, i32 %i0, 0490  call void @foo()491  br label %end492 493right:494  %i3 = extractvalue { i32, i32 } %agg_right, 0495  %i4 = extractvalue { i32, i32 } %agg_right, 1496  %i5 = insertvalue { i32, i32 } undef, i32 %i3, 0497  call void @bar()498  br label %end499 500end:501  %i6 = phi { i32, i32 } [ %i2, %left ], [ %i5, %right ]502  %i7 = phi i32 [ %i1, %left ], [ %i4, %right ]503  call void @baz()504  %i8 = insertvalue { i32, i32 } %i6, i32 %i7, 1505  ret { i32, i32 } %i8506}507