|  | ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py | 
|  | ; RUN: opt %s -mtriple=x86_64-- -codegenprepare -S | FileCheck %s | 
|  | @g = global i32 0 | 
|  | @effect = global i32 0 | 
|  |  | 
|  | define void @switch_phi_const(i32 %x) { | 
|  | ; CHECK-LABEL: @switch_phi_const( | 
|  | ; CHECK-NEXT:  bb0: | 
|  | ; CHECK-NEXT:    switch i32 [[X:%.*]], label [[DEFAULT:%.*]] [ | 
|  | ; CHECK-NEXT:    i32 13, label [[CASE_13:%.*]] | 
|  | ; CHECK-NEXT:    i32 42, label [[CASE_42:%.*]] | 
|  | ; CHECK-NEXT:    i32 50, label [[CASE_50_51:%.*]] | 
|  | ; CHECK-NEXT:    i32 51, label [[CASE_50_51]] | 
|  | ; CHECK-NEXT:    i32 55, label [[CASE_55:%.*]] | 
|  | ; CHECK-NEXT:    i32 7, label [[CASE_7:%.*]] | 
|  | ; CHECK-NEXT:    ] | 
|  | ; CHECK:       case_13: | 
|  | ; CHECK-NEXT:    [[X0:%.*]] = phi i32 [ [[X]], [[BB0:%.*]] ], [ [[X_LOOPBACK:%.*]], [[CASE_7]] ] | 
|  | ; CHECK-NEXT:    store i32 13, ptr @effect, align 4 | 
|  | ; CHECK-NEXT:    br label [[CASE_42]] | 
|  | ; CHECK:       case_42: | 
|  | ; CHECK-NEXT:    [[X1:%.*]] = phi i32 [ [[X]], [[BB0]] ], [ [[X0]], [[CASE_13]] ] | 
|  | ; CHECK-NEXT:    store i32 [[X1]], ptr @effect, align 4 | 
|  | ; CHECK-NEXT:    br label [[CASE_50_51]] | 
|  | ; CHECK:       case_50_51: | 
|  | ; CHECK-NEXT:    [[X2:%.*]] = phi i32 [ 50, [[BB0]] ], [ 50, [[BB0]] ], [ [[X1]], [[CASE_42]] ] | 
|  | ; CHECK-NEXT:    [[X2_2:%.*]] = phi i32 [ 51, [[BB0]] ], [ 51, [[BB0]] ], [ [[X1]], [[CASE_42]] ] | 
|  | ; CHECK-NEXT:    store i32 [[X2]], ptr @effect, align 4 | 
|  | ; CHECK-NEXT:    store i32 [[X2_2]], ptr @effect, align 4 | 
|  | ; CHECK-NEXT:    br label [[CASE_55]] | 
|  | ; CHECK:       case_55: | 
|  | ; CHECK-NEXT:    [[X3:%.*]] = phi i32 [ 42, [[BB0]] ], [ 55, [[CASE_50_51]] ] | 
|  | ; CHECK-NEXT:    store i32 [[X3]], ptr @effect, align 4 | 
|  | ; CHECK-NEXT:    br label [[DEFAULT]] | 
|  | ; CHECK:       case_7: | 
|  | ; CHECK-NEXT:    [[X_LOOPBACK]] = load i32, ptr @g, align 4 | 
|  | ; CHECK-NEXT:    store i32 7, ptr @effect, align 4 | 
|  | ; CHECK-NEXT:    br label [[CASE_13]] | 
|  | ; CHECK:       default: | 
|  | ; CHECK-NEXT:    ret void | 
|  | ; | 
|  | bb0: | 
|  | switch i32 %x, label %default [ | 
|  | i32 13, label %case_13 | 
|  | i32 42, label %case_42 | 
|  | i32 50, label %case_50_51 | 
|  | i32 51, label %case_50_51 | 
|  | i32 55, label %case_55 | 
|  | i32 7, label %case_7 | 
|  | ] | 
|  |  | 
|  | case_13: | 
|  | ; We should replace 13 with %x | 
|  | %x0 = phi i32 [ 13, %bb0 ], [ %x_loopback, %case_7 ] | 
|  | store i32 13, ptr @effect, align 4 | 
|  | br label %case_42 | 
|  |  | 
|  | case_42: | 
|  | ; We should replace 42 with %x | 
|  | %x1 = phi i32 [ 42, %bb0 ], [ %x0, %case_13 ] | 
|  | store i32 %x1, ptr @effect, align 4 | 
|  | br label %case_50_51 | 
|  |  | 
|  | case_50_51: | 
|  | ; Must not replace the PHI argument: Case values 50 and 51 jump here. | 
|  | %x2 = phi i32 [ 50, %bb0 ], [ 50, %bb0 ], [ %x1, %case_42 ] | 
|  | %x2.2 = phi i32 [ 51, %bb0 ], [ 51, %bb0 ], [ %x1, %case_42 ] | 
|  | store i32 %x2, ptr @effect, align 4 | 
|  | store i32 %x2.2, ptr @effect, align 4 | 
|  | br label %case_55 | 
|  |  | 
|  | case_55: | 
|  | ; We must not replace any of the PHI arguments: | 
|  | ; - 42 is the wrong constant | 
|  | ; - %case_42 is not the switch predecessor block. | 
|  | %x3 = phi i32 [ 42, %bb0 ], [ 55, %case_50_51 ] | 
|  | store i32 %x3, ptr @effect, align 4 | 
|  | br label %default | 
|  |  | 
|  | case_7: | 
|  | %x_loopback = load i32, ptr @g, align 4 | 
|  | store i32 7, ptr @effect, align 4 | 
|  | br label %case_13 | 
|  |  | 
|  | default: | 
|  | ret void | 
|  | } | 
|  |  | 
|  | define void @switch_phi_const_multiple_phis(i32 %x, i1 %c) { | 
|  | ; CHECK-LABEL: @switch_phi_const_multiple_phis( | 
|  | ; CHECK-NEXT:  bb0: | 
|  | ; CHECK-NEXT:    br i1 [[C:%.*]], label [[BB1:%.*]], label [[CASE_13:%.*]] | 
|  | ; CHECK:       bb1: | 
|  | ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[X:%.*]], 13 | 
|  | ; CHECK-NEXT:    br i1 [[COND]], label [[CASE_13]], label [[DEFAULT:%.*]] | 
|  | ; CHECK:       case_13: | 
|  | ; CHECK-NEXT:    [[X0:%.*]] = phi i32 [ [[X]], [[BB1]] ], [ 1, [[BB0:%.*]] ] | 
|  | ; CHECK-NEXT:    [[N0:%.*]] = phi i32 [ 14, [[BB1]] ], [ 1, [[BB0]] ] | 
|  | ; CHECK-NEXT:    [[X1:%.*]] = phi i32 [ 27, [[BB0]] ], [ [[X]], [[BB1]] ] | 
|  | ; CHECK-NEXT:    store volatile i32 [[X0]], ptr @effect, align 4 | 
|  | ; CHECK-NEXT:    store volatile i32 [[N0]], ptr @effect, align 4 | 
|  | ; CHECK-NEXT:    store volatile i32 [[X1]], ptr @effect, align 4 | 
|  | ; CHECK-NEXT:    ret void | 
|  | ; CHECK:       default: | 
|  | ; CHECK-NEXT:    ret void | 
|  | ; | 
|  | bb0: | 
|  | br i1 %c, label %bb1, label %case_13 | 
|  |  | 
|  | bb1: | 
|  | switch i32 %x, label %default [ | 
|  | i32 13, label %case_13 | 
|  | ] | 
|  |  | 
|  | case_13: | 
|  | ; Check that replacement works for multiple PHIs. | 
|  | ; Should perform replacement for %x0, %x1 but not %n0 | 
|  | %x0 = phi i32 [13, %bb1], [1, %bb0] | 
|  | %n0 = phi i32 [14, %bb1], [1, %bb0] | 
|  | %x1 = phi i32 [27, %bb0], [13, %bb1] | 
|  | store volatile i32 %x0, ptr @effect, align 4 | 
|  | store volatile i32 %n0, ptr @effect, align 4 | 
|  | store volatile i32 %x1, ptr @effect, align 4 | 
|  | ret void | 
|  |  | 
|  | default: | 
|  | ret void | 
|  | } | 
|  |  | 
|  | define void @switch_phi_const_degenerate(i1 %c) { | 
|  | ; CHECK-LABEL: @switch_phi_const_degenerate( | 
|  | ; CHECK-NEXT:  bb0: | 
|  | ; CHECK-NEXT:    br i1 [[C:%.*]], label [[CASE_42:%.*]], label [[BB1:%.*]] | 
|  | ; CHECK:       bb1: | 
|  | ; CHECK-NEXT:    br label [[CASE_42]] | 
|  | ; CHECK:       case_42: | 
|  | ; CHECK-NEXT:    [[X:%.*]] = phi i32 [ 0, [[BB0:%.*]] ], [ 42, [[BB1]] ] | 
|  | ; CHECK-NEXT:    store volatile i32 [[X]], ptr @effect, align 4 | 
|  | ; CHECK-NEXT:    ret void | 
|  | ; | 
|  | bb0: | 
|  | br i1 %c, label %case_42, label %bb1 | 
|  |  | 
|  | bb1: | 
|  | switch i32 42, label %unreachable [ | 
|  | i32 42, label %case_42 | 
|  | ] | 
|  |  | 
|  | case_42: | 
|  | ; We should not end up in an endless loop 42 with the switch condition 42. | 
|  | %x = phi i32 [0, %bb0], [42, %bb1] | 
|  | store volatile i32 %x, ptr @effect, align 4 | 
|  | ret void | 
|  |  | 
|  | unreachable: | 
|  | unreachable | 
|  | } | 
|  |  | 
|  | @g64 = global i64 0 | 
|  | @effect64 = global i64 0 | 
|  |  | 
|  | define void @switch_trunc_phi_const(i32 %x) { | 
|  | ; CHECK-LABEL: @switch_trunc_phi_const( | 
|  | ; CHECK-NEXT:  bb0: | 
|  | ; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[X:%.*]] to i64 | 
|  | ; CHECK-NEXT:    [[TMP1:%.*]] = zext i32 [[X]] to i64 | 
|  | ; CHECK-NEXT:    switch i32 [[X]], label [[DEFAULT:%.*]] [ | 
|  | ; CHECK-NEXT:    i32 13, label [[CASE_13:%.*]] | 
|  | ; CHECK-NEXT:    i32 42, label [[CASE_42:%.*]] | 
|  | ; CHECK-NEXT:    i32 55, label [[CASE_55:%.*]] | 
|  | ; CHECK-NEXT:    i32 7, label [[CASE_7:%.*]] | 
|  | ; CHECK-NEXT:    ] | 
|  | ; CHECK:       case_13: | 
|  | ; CHECK-NEXT:    [[X0:%.*]] = phi i64 [ [[TMP0]], [[BB0:%.*]] ], [ [[X7:%.*]], [[CASE_7]] ] | 
|  | ; CHECK-NEXT:    store i64 13, ptr @effect64, align 4 | 
|  | ; CHECK-NEXT:    br label [[CASE_42]] | 
|  | ; CHECK:       case_42: | 
|  | ; CHECK-NEXT:    [[X1:%.*]] = phi i64 [ [[TMP1]], [[BB0]] ], [ [[X0]], [[CASE_13]] ] | 
|  | ; CHECK-NEXT:    store i64 [[X1]], ptr @effect64, align 4 | 
|  | ; CHECK-NEXT:    br label [[CASE_55]] | 
|  | ; CHECK:       case_55: | 
|  | ; CHECK-NEXT:    [[X2:%.*]] = phi i64 [ 3895, [[BB0]] ], [ 55, [[CASE_42]] ] | 
|  | ; CHECK-NEXT:    store i64 [[X2]], ptr @effect64, align 4 | 
|  | ; CHECK-NEXT:    br label [[DEFAULT]] | 
|  | ; CHECK:       case_7: | 
|  | ; CHECK-NEXT:    [[X7]] = load i64, ptr @g64, align 4 | 
|  | ; CHECK-NEXT:    store i64 7, ptr @effect64, align 4 | 
|  | ; CHECK-NEXT:    br label [[CASE_13]] | 
|  | ; CHECK:       default: | 
|  | ; CHECK-NEXT:    ret void | 
|  | ; | 
|  | bb0: | 
|  | switch i32 %x, label %default [ | 
|  | i32 13, label %case_13 | 
|  | i32 42, label %case_42 | 
|  | i32 55, label %case_55 | 
|  | i32 7, label %case_7 | 
|  | ] | 
|  |  | 
|  | case_13: | 
|  | ; We should replace 13 with zext %x to i64 | 
|  | %x0 = phi i64 [ 13, %bb0 ], [ %x7, %case_7 ] | 
|  | store i64 13, ptr @effect64, align 4 | 
|  | br label %case_42 | 
|  |  | 
|  | case_42: | 
|  | ; We should replace 42 with zext i32 %x to i64 | 
|  | %x1 = phi i64 [ 42, %bb0 ], [ %x0, %case_13 ] | 
|  | store i64 %x1, ptr @effect64, align 4 | 
|  | br label %case_55 | 
|  |  | 
|  | case_55: | 
|  | ; We must not replace any of the PHI arguments! (3898 == 0xf00 + 55) | 
|  | %x2 = phi i64 [ 3895, %bb0 ], [ 55, %case_42 ] | 
|  | store i64 %x2, ptr @effect64, align 4 | 
|  | br label %default | 
|  |  | 
|  | case_7: | 
|  | %x7 = load i64, ptr @g64, align 4 | 
|  | store i64 7, ptr @effect64, align 4 | 
|  | br label %case_13 | 
|  |  | 
|  | default: | 
|  | ret void | 
|  | } |