1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -S -passes=instcombine | FileCheck %s 3@A = extern_weak global i32, align 4 4@B = extern_weak global i32, align 4 5 6define i32 @foo(i1 %which) { 7; CHECK-LABEL: @foo( 8; CHECK-NEXT: entry: 9; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]] 10; CHECK: delay: 11; CHECK-NEXT: br label [[FINAL]] 12; CHECK: final: 13; CHECK-NEXT: [[USE2:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ select (i1 icmp eq (i32* @A, i32* @B), i32 2, i32 1), [[DELAY]] ] 14; CHECK-NEXT: ret i32 [[USE2]] 15; 16entry: 17 br i1 %which, label %final, label %delay 18 19delay: 20 br label %final 21 22final: 23 %use2 = phi i1 [ false, %entry ], [ icmp eq (i32* @A, i32* @B), %delay ] 24 %value = select i1 %use2, i32 2, i32 1 25 ret i32 %value 26} 27 28 29; test folding of select into phi for vectors. 30define <4 x i64> @vec1(i1 %which) { 31; CHECK-LABEL: @vec1( 32; CHECK-NEXT: entry: 33; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]] 34; CHECK: delay: 35; CHECK-NEXT: br label [[FINAL]] 36; CHECK: final: 37; CHECK-NEXT: [[PHINODE:%.*]] = phi <4 x i64> [ zeroinitializer, [[ENTRY:%.*]] ], [ <i64 0, i64 0, i64 126, i64 127>, [[DELAY]] ] 38; CHECK-NEXT: ret <4 x i64> [[PHINODE]] 39; 40entry: 41 br i1 %which, label %final, label %delay 42 43delay: 44 br label %final 45 46final: 47 %phinode = phi <4 x i1> [ <i1 true, i1 true, i1 true, i1 true>, %entry ], [ <i1 true, i1 true, i1 false, i1 false>, %delay ] 48 %sel = select <4 x i1> %phinode, <4 x i64> zeroinitializer, <4 x i64> <i64 124, i64 125, i64 126, i64 127> 49 ret <4 x i64> %sel 50} 51 52define <4 x i64> @vec2(i1 %which) { 53; CHECK-LABEL: @vec2( 54; CHECK-NEXT: entry: 55; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]] 56; CHECK: delay: 57; CHECK-NEXT: br label [[FINAL]] 58; CHECK: final: 59; CHECK-NEXT: [[PHINODE:%.*]] = phi <4 x i64> [ <i64 124, i64 125, i64 126, i64 127>, [[ENTRY:%.*]] ], [ <i64 0, i64 125, i64 0, i64 127>, [[DELAY]] ] 60; CHECK-NEXT: ret <4 x i64> [[PHINODE]] 61; 62entry: 63 br i1 %which, label %final, label %delay 64 65delay: 66 br label %final 67 68final: 69 %phinode = phi <4 x i1> [ <i1 false, i1 false, i1 false, i1 false>, %entry ], [ <i1 true, i1 false, i1 true, i1 false>, %delay ] 70 %sel = select <4 x i1> %phinode, <4 x i64> zeroinitializer, <4 x i64> <i64 124, i64 125, i64 126, i64 127> 71 ret <4 x i64> %sel 72} 73 74; Test PR33364 75; Insert the generated select into the same block as the incoming phi value. 76; phi has constant vectors along with a single non-constant vector as operands. 77define <2 x i8> @vec3(i1 %cond1, i1 %cond2, <2 x i1> %x, <2 x i8> %y, <2 x i8> %z) { 78; CHECK-LABEL: @vec3( 79; CHECK-NEXT: entry: 80; CHECK-NEXT: [[PHI_SEL1:%.*]] = shufflevector <2 x i8> [[Z:%.*]], <2 x i8> [[Y:%.*]], <2 x i32> <i32 0, i32 3> 81; CHECK-NEXT: br i1 [[COND1:%.*]], label [[IF1:%.*]], label [[ELSE:%.*]] 82; CHECK: if1: 83; CHECK-NEXT: [[PHI_SEL2:%.*]] = shufflevector <2 x i8> [[Y]], <2 x i8> [[Z]], <2 x i32> <i32 0, i32 3> 84; CHECK-NEXT: br i1 [[COND2:%.*]], label [[IF2:%.*]], label [[ELSE]] 85; CHECK: if2: 86; CHECK-NEXT: [[PHI_SEL:%.*]] = select <2 x i1> [[X:%.*]], <2 x i8> [[Y]], <2 x i8> [[Z]] 87; CHECK-NEXT: br label [[ELSE]] 88; CHECK: else: 89; CHECK-NEXT: [[PHI:%.*]] = phi <2 x i8> [ [[PHI_SEL]], [[IF2]] ], [ [[PHI_SEL1]], [[ENTRY:%.*]] ], [ [[PHI_SEL2]], [[IF1]] ] 90; CHECK-NEXT: ret <2 x i8> [[PHI]] 91; 92entry: 93 br i1 %cond1, label %if1, label %else 94 95if1: 96 br i1 %cond2, label %if2, label %else 97 98if2: 99 br label %else 100 101else: 102 %phi = phi <2 x i1> [ %x, %if2 ], [ <i1 0, i1 1>, %entry ], [ <i1 1, i1 0>, %if1 ] 103 %sel = select <2 x i1> %phi, <2 x i8> %y, <2 x i8> %z 104 ret <2 x i8> %sel 105} 106 107; Don't crash on unreachable IR. 108 109define void @PR48369(i32 %a, i32* %p) { 110; CHECK-LABEL: @PR48369( 111; CHECK-NEXT: entry: 112; CHECK-NEXT: [[PHI_CMP:%.*]] = icmp sgt i32 [[A:%.*]], 0 113; CHECK-NEXT: br label [[BB1:%.*]] 114; CHECK: bb1: 115; CHECK-NEXT: [[CMP:%.*]] = phi i1 [ [[PHI_CMP]], [[DEADBB:%.*]] ], [ true, [[ENTRY:%.*]] ] 116; CHECK-NEXT: [[SHL:%.*]] = select i1 [[CMP]], i32 256, i32 0 117; CHECK-NEXT: store i32 [[SHL]], i32* [[P:%.*]], align 4 118; CHECK-NEXT: br label [[END:%.*]] 119; CHECK: deadbb: 120; CHECK-NEXT: br label [[BB1]] 121; CHECK: end: 122; CHECK-NEXT: ret void 123; 124entry: 125 %phi.cmp = icmp sgt i32 %a, 0 126 br label %bb1 127 128bb1: 129 %cmp = phi i1 [ %phi.cmp, %deadbb ], [ true, %entry ] 130 %shl = select i1 %cmp, i32 256, i32 0 131 store i32 %shl, i32* %p 132 br label %end 133 134deadbb: 135 br label %bb1 136 137end: 138 ret void 139} 140 141define i16 @sink_to_unreachable_crash(i1 %a) { 142; CHECK-LABEL: @sink_to_unreachable_crash( 143; CHECK-NEXT: entry: 144; CHECK-NEXT: [[S:%.*]] = select i1 [[A:%.*]], i16 0, i16 5 145; CHECK-NEXT: br label [[INF_LOOP:%.*]] 146; CHECK: inf_loop: 147; CHECK-NEXT: br label [[INF_LOOP]] 148; CHECK: unreachable: 149; CHECK-NEXT: ret i16 [[S]] 150; 151entry: 152 %s = select i1 %a, i16 0, i16 5 153 br label %inf_loop 154 155inf_loop: 156 br label %inf_loop 157 158unreachable: ; No predecessors! 159 ret i16 %s 160} 161