1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt %s -mtriple=x86_64-- -codegenprepare -S | FileCheck %s 3@g = global i32 0 4@effect = global i32 0 5 6define void @switch_phi_const(i32 %x) { 7; CHECK-LABEL: @switch_phi_const( 8; CHECK-NEXT: bb0: 9; CHECK-NEXT: switch i32 [[X:%.*]], label [[DEFAULT:%.*]] [ 10; CHECK-NEXT: i32 13, label [[CASE_13:%.*]] 11; CHECK-NEXT: i32 42, label [[CASE_42:%.*]] 12; CHECK-NEXT: i32 50, label [[CASE_50_51:%.*]] 13; CHECK-NEXT: i32 51, label [[CASE_50_51]] 14; CHECK-NEXT: i32 55, label [[CASE_55:%.*]] 15; CHECK-NEXT: i32 7, label [[CASE_7:%.*]] 16; CHECK-NEXT: ] 17; CHECK: case_13: 18; CHECK-NEXT: [[X0:%.*]] = phi i32 [ [[X]], [[BB0:%.*]] ], [ [[X_LOOPBACK:%.*]], [[CASE_7]] ] 19; CHECK-NEXT: store i32 13, ptr @effect, align 4 20; CHECK-NEXT: br label [[CASE_42]] 21; CHECK: case_42: 22; CHECK-NEXT: [[X1:%.*]] = phi i32 [ [[X]], [[BB0]] ], [ [[X0]], [[CASE_13]] ] 23; CHECK-NEXT: store i32 [[X1]], ptr @effect, align 4 24; CHECK-NEXT: br label [[CASE_50_51]] 25; CHECK: case_50_51: 26; CHECK-NEXT: [[X2:%.*]] = phi i32 [ 50, [[BB0]] ], [ 50, [[BB0]] ], [ [[X1]], [[CASE_42]] ] 27; CHECK-NEXT: [[X2_2:%.*]] = phi i32 [ 51, [[BB0]] ], [ 51, [[BB0]] ], [ [[X1]], [[CASE_42]] ] 28; CHECK-NEXT: store i32 [[X2]], ptr @effect, align 4 29; CHECK-NEXT: store i32 [[X2_2]], ptr @effect, align 4 30; CHECK-NEXT: br label [[CASE_55]] 31; CHECK: case_55: 32; CHECK-NEXT: [[X3:%.*]] = phi i32 [ 42, [[BB0]] ], [ 55, [[CASE_50_51]] ] 33; CHECK-NEXT: store i32 [[X3]], ptr @effect, align 4 34; CHECK-NEXT: br label [[DEFAULT]] 35; CHECK: case_7: 36; CHECK-NEXT: [[X_LOOPBACK]] = load i32, ptr @g, align 4 37; CHECK-NEXT: store i32 7, ptr @effect, align 4 38; CHECK-NEXT: br label [[CASE_13]] 39; CHECK: default: 40; CHECK-NEXT: ret void 41; 42bb0: 43 switch i32 %x, label %default [ 44 i32 13, label %case_13 45 i32 42, label %case_42 46 i32 50, label %case_50_51 47 i32 51, label %case_50_51 48 i32 55, label %case_55 49 i32 7, label %case_7 50 ] 51 52case_13: 53 ; We should replace 13 with %x 54 %x0 = phi i32 [ 13, %bb0 ], [ %x_loopback, %case_7 ] 55 store i32 13, ptr @effect, align 4 56 br label %case_42 57 58case_42: 59 ; We should replace 42 with %x 60 %x1 = phi i32 [ 42, %bb0 ], [ %x0, %case_13 ] 61 store i32 %x1, ptr @effect, align 4 62 br label %case_50_51 63 64case_50_51: 65 ; Must not replace the PHI argument: Case values 50 and 51 jump here. 66 %x2 = phi i32 [ 50, %bb0 ], [ 50, %bb0 ], [ %x1, %case_42 ] 67 %x2.2 = phi i32 [ 51, %bb0 ], [ 51, %bb0 ], [ %x1, %case_42 ] 68 store i32 %x2, ptr @effect, align 4 69 store i32 %x2.2, ptr @effect, align 4 70 br label %case_55 71 72case_55: 73 ; We must not replace any of the PHI arguments: 74 ; - 42 is the wrong constant 75 ; - %case_42 is not the switch predecessor block. 76 %x3 = phi i32 [ 42, %bb0 ], [ 55, %case_50_51 ] 77 store i32 %x3, ptr @effect, align 4 78 br label %default 79 80case_7: 81 %x_loopback = load i32, ptr @g, align 4 82 store i32 7, ptr @effect, align 4 83 br label %case_13 84 85default: 86 ret void 87} 88 89define void @switch_phi_const_multiple_phis(i32 %x, i1 %c) { 90; CHECK-LABEL: @switch_phi_const_multiple_phis( 91; CHECK-NEXT: bb0: 92; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[CASE_13:%.*]] 93; CHECK: bb1: 94; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[X:%.*]], 13 95; CHECK-NEXT: br i1 [[COND]], label [[CASE_13]], label [[DEFAULT:%.*]] 96; CHECK: case_13: 97; CHECK-NEXT: [[X0:%.*]] = phi i32 [ [[X]], [[BB1]] ], [ 1, [[BB0:%.*]] ] 98; CHECK-NEXT: [[N0:%.*]] = phi i32 [ 14, [[BB1]] ], [ 1, [[BB0]] ] 99; CHECK-NEXT: [[X1:%.*]] = phi i32 [ 27, [[BB0]] ], [ [[X]], [[BB1]] ] 100; CHECK-NEXT: store volatile i32 [[X0]], ptr @effect, align 4 101; CHECK-NEXT: store volatile i32 [[N0]], ptr @effect, align 4 102; CHECK-NEXT: store volatile i32 [[X1]], ptr @effect, align 4 103; CHECK-NEXT: ret void 104; CHECK: default: 105; CHECK-NEXT: ret void 106; 107bb0: 108 br i1 %c, label %bb1, label %case_13 109 110bb1: 111 switch i32 %x, label %default [ 112 i32 13, label %case_13 113 ] 114 115case_13: 116 ; Check that replacement works for multiple PHIs. 117 ; Should perform replacement for %x0, %x1 but not %n0 118 %x0 = phi i32 [13, %bb1], [1, %bb0] 119 %n0 = phi i32 [14, %bb1], [1, %bb0] 120 %x1 = phi i32 [27, %bb0], [13, %bb1] 121 store volatile i32 %x0, ptr @effect, align 4 122 store volatile i32 %n0, ptr @effect, align 4 123 store volatile i32 %x1, ptr @effect, align 4 124 ret void 125 126default: 127 ret void 128} 129 130define void @switch_phi_const_degenerate(i1 %c) { 131; CHECK-LABEL: @switch_phi_const_degenerate( 132; CHECK-NEXT: bb0: 133; CHECK-NEXT: br i1 [[C:%.*]], label [[CASE_42:%.*]], label [[BB1:%.*]] 134; CHECK: bb1: 135; CHECK-NEXT: br label [[CASE_42]] 136; CHECK: case_42: 137; CHECK-NEXT: [[X:%.*]] = phi i32 [ 0, [[BB0:%.*]] ], [ 42, [[BB1]] ] 138; CHECK-NEXT: store volatile i32 [[X]], ptr @effect, align 4 139; CHECK-NEXT: ret void 140; 141bb0: 142 br i1 %c, label %case_42, label %bb1 143 144bb1: 145 switch i32 42, label %unreachable [ 146 i32 42, label %case_42 147 ] 148 149case_42: 150 ; We should not end up in an endless loop 42 with the switch condition 42. 151 %x = phi i32 [0, %bb0], [42, %bb1] 152 store volatile i32 %x, ptr @effect, align 4 153 ret void 154 155unreachable: 156 unreachable 157} 158 159@g64 = global i64 0 160@effect64 = global i64 0 161 162define void @switch_trunc_phi_const(i32 %x) { 163; CHECK-LABEL: @switch_trunc_phi_const( 164; CHECK-NEXT: bb0: 165; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[X:%.*]] to i64 166; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[X]] to i64 167; CHECK-NEXT: switch i32 [[X]], label [[DEFAULT:%.*]] [ 168; CHECK-NEXT: i32 13, label [[CASE_13:%.*]] 169; CHECK-NEXT: i32 42, label [[CASE_42:%.*]] 170; CHECK-NEXT: i32 55, label [[CASE_55:%.*]] 171; CHECK-NEXT: i32 7, label [[CASE_7:%.*]] 172; CHECK-NEXT: ] 173; CHECK: case_13: 174; CHECK-NEXT: [[X0:%.*]] = phi i64 [ [[TMP0]], [[BB0:%.*]] ], [ [[X7:%.*]], [[CASE_7]] ] 175; CHECK-NEXT: store i64 13, ptr @effect64, align 4 176; CHECK-NEXT: br label [[CASE_42]] 177; CHECK: case_42: 178; CHECK-NEXT: [[X1:%.*]] = phi i64 [ [[TMP1]], [[BB0]] ], [ [[X0]], [[CASE_13]] ] 179; CHECK-NEXT: store i64 [[X1]], ptr @effect64, align 4 180; CHECK-NEXT: br label [[CASE_55]] 181; CHECK: case_55: 182; CHECK-NEXT: [[X2:%.*]] = phi i64 [ 3895, [[BB0]] ], [ 55, [[CASE_42]] ] 183; CHECK-NEXT: store i64 [[X2]], ptr @effect64, align 4 184; CHECK-NEXT: br label [[DEFAULT]] 185; CHECK: case_7: 186; CHECK-NEXT: [[X7]] = load i64, ptr @g64, align 4 187; CHECK-NEXT: store i64 7, ptr @effect64, align 4 188; CHECK-NEXT: br label [[CASE_13]] 189; CHECK: default: 190; CHECK-NEXT: ret void 191; 192bb0: 193 switch i32 %x, label %default [ 194 i32 13, label %case_13 195 i32 42, label %case_42 196 i32 55, label %case_55 197 i32 7, label %case_7 198 ] 199 200case_13: 201 ; We should replace 13 with zext %x to i64 202 %x0 = phi i64 [ 13, %bb0 ], [ %x7, %case_7 ] 203 store i64 13, ptr @effect64, align 4 204 br label %case_42 205 206case_42: 207 ; We should replace 42 with zext i32 %x to i64 208 %x1 = phi i64 [ 42, %bb0 ], [ %x0, %case_13 ] 209 store i64 %x1, ptr @effect64, align 4 210 br label %case_55 211 212case_55: 213 ; We must not replace any of the PHI arguments! (3898 == 0xf00 + 55) 214 %x2 = phi i64 [ 3895, %bb0 ], [ 55, %case_42 ] 215 store i64 %x2, ptr @effect64, align 4 216 br label %default 217 218case_7: 219 %x7 = load i64, ptr @g64, align 4 220 store i64 7, ptr @effect64, align 4 221 br label %case_13 222 223default: 224 ret void 225} 226