1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -S -passes=instcombine < %s | FileCheck %s 3 4; 5; Tests to show cases where computeKnownBits should be able to determine 6; the known bits of a phi edge based off a conditional branch feeding the phi. 7; 8 9; %x either eq 7 or is set to 7 10define i64 @limit_i64_eq_7(i64 %x) { 11; CHECK-LABEL: @limit_i64_eq_7( 12; CHECK-NEXT: entry: 13; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[X:%.*]], 7 14; CHECK-NEXT: br i1 [[CMP]], label [[END:%.*]], label [[BODY:%.*]] 15; CHECK: body: 16; CHECK-NEXT: br label [[END]] 17; CHECK: end: 18; CHECK-NEXT: [[RES:%.*]] = phi i64 [ [[X]], [[ENTRY:%.*]] ], [ 7, [[BODY]] ] 19; CHECK-NEXT: ret i64 [[RES]] 20; 21entry: 22 %cmp = icmp eq i64 %x, 7 23 br i1 %cmp, label %end, label %body 24body: 25 br label %end 26end: 27 %res = phi i64 [ %x, %entry ], [ 7, %body ] 28 ret i64 %res 29} 30 31; %x either eq 255 or is set to 255 32define i64 @limit_i64_ne_255(i64 %x) { 33; CHECK-LABEL: @limit_i64_ne_255( 34; CHECK-NEXT: entry: 35; CHECK-NEXT: [[CMP:%.*]] = icmp ne i64 [[X:%.*]], 255 36; CHECK-NEXT: call void @use(i1 [[CMP]]) 37; CHECK-NEXT: br i1 [[CMP]], label [[BODY:%.*]], label [[END:%.*]] 38; CHECK: body: 39; CHECK-NEXT: br label [[END]] 40; CHECK: end: 41; CHECK-NEXT: [[RES:%.*]] = phi i64 [ [[X]], [[ENTRY:%.*]] ], [ 255, [[BODY]] ] 42; CHECK-NEXT: ret i64 [[RES]] 43; 44entry: 45 %cmp = icmp ne i64 %x, 255 46 call void @use(i1 %cmp) 47 br i1 %cmp, label %body, label %end 48body: 49 br label %end 50end: 51 %res = phi i64 [ %x, %entry ], [ 255, %body ] 52 ret i64 %res 53} 54declare void @use(i1) 55 56; %x either ule 15 or is masked with 15 57define i64 @limit_i64_ule_15(i64 %x) { 58; CHECK-LABEL: @limit_i64_ule_15( 59; CHECK-NEXT: entry: 60; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[X:%.*]], 16 61; CHECK-NEXT: br i1 [[CMP]], label [[END:%.*]], label [[BODY:%.*]] 62; CHECK: body: 63; CHECK-NEXT: [[MASK:%.*]] = and i64 [[X]], 15 64; CHECK-NEXT: br label [[END]] 65; CHECK: end: 66; CHECK-NEXT: [[X_MASK:%.*]] = phi i64 [ [[X]], [[ENTRY:%.*]] ], [ [[MASK]], [[BODY]] ] 67; CHECK-NEXT: ret i64 [[X_MASK]] 68; 69entry: 70 %cmp = icmp ule i64 %x, 15 71 br i1 %cmp, label %end, label %body 72body: 73 %mask = and i64 %x, 15 74 br label %end 75end: 76 %x.mask = phi i64 [ %x, %entry ], [ %mask, %body ] 77 %res = and i64 %x.mask, 15 78 ret i64 %res 79} 80 81; %x either uge 8 or is masked with 7 82define i64 @limit_i64_uge_8(i64 %x) { 83; CHECK-LABEL: @limit_i64_uge_8( 84; CHECK-NEXT: entry: 85; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i64 [[X:%.*]], 7 86; CHECK-NEXT: br i1 [[CMP]], label [[BODY:%.*]], label [[END:%.*]] 87; CHECK: body: 88; CHECK-NEXT: [[MASK:%.*]] = and i64 [[X]], 7 89; CHECK-NEXT: br label [[END]] 90; CHECK: end: 91; CHECK-NEXT: [[X_MASK:%.*]] = phi i64 [ [[X]], [[ENTRY:%.*]] ], [ [[MASK]], [[BODY]] ] 92; CHECK-NEXT: ret i64 [[X_MASK]] 93; 94entry: 95 %cmp = icmp uge i64 %x, 8 96 br i1 %cmp, label %body, label %end 97body: 98 %mask = and i64 %x, 7 99 br label %end 100end: 101 %x.mask = phi i64 [ %x, %entry ], [ %mask, %body ] 102 %res = and i64 %x.mask, 7 103 ret i64 %res 104} 105 106; %x either ult 8 or is masked with 7 107define i64 @limit_i64_ult_8(i64 %x) { 108; CHECK-LABEL: @limit_i64_ult_8( 109; CHECK-NEXT: entry: 110; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[X:%.*]], 8 111; CHECK-NEXT: br i1 [[CMP]], label [[END:%.*]], label [[BODY:%.*]] 112; CHECK: body: 113; CHECK-NEXT: [[MASK:%.*]] = and i64 [[X]], 7 114; CHECK-NEXT: br label [[END]] 115; CHECK: end: 116; CHECK-NEXT: [[X_MASK:%.*]] = phi i64 [ [[X]], [[ENTRY:%.*]] ], [ [[MASK]], [[BODY]] ] 117; CHECK-NEXT: ret i64 [[X_MASK]] 118; 119entry: 120 %cmp = icmp ult i64 %x, 8 121 br i1 %cmp, label %end, label %body 122body: 123 %mask = and i64 %x, 7 124 br label %end 125end: 126 %x.mask = phi i64 [ %x, %entry ], [ %mask, %body ] 127 %res = and i64 %x.mask, 7 128 ret i64 %res 129} 130 131; %x either ugt 7 or is masked with 7 132define i64 @limit_i64_ugt_7(i64 %x) { 133; CHECK-LABEL: @limit_i64_ugt_7( 134; CHECK-NEXT: entry: 135; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i64 [[X:%.*]], 7 136; CHECK-NEXT: br i1 [[CMP]], label [[BODY:%.*]], label [[END:%.*]] 137; CHECK: body: 138; CHECK-NEXT: [[MASK:%.*]] = and i64 [[X]], 7 139; CHECK-NEXT: br label [[END]] 140; CHECK: end: 141; CHECK-NEXT: [[X_MASK:%.*]] = phi i64 [ [[X]], [[ENTRY:%.*]] ], [ [[MASK]], [[BODY]] ] 142; CHECK-NEXT: ret i64 [[X_MASK]] 143; 144entry: 145 %cmp = icmp ugt i64 %x, 7 146 br i1 %cmp, label %body, label %end 147body: 148 %mask = and i64 %x, 7 149 br label %end 150end: 151 %x.mask = phi i64 [ %x, %entry ], [ %mask, %body ] 152 %res = and i64 %x.mask, 7 153 ret i64 %res 154} 155 156; 157; negative tests 158; 159 160; %x either ule 15 or is masked with 15 161define i64 @limit_i64_ule_15_mask3(i64 %x) { 162; CHECK-LABEL: @limit_i64_ule_15_mask3( 163; CHECK-NEXT: entry: 164; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[X:%.*]], 16 165; CHECK-NEXT: br i1 [[CMP]], label [[END:%.*]], label [[BODY:%.*]] 166; CHECK: body: 167; CHECK-NEXT: [[MASK:%.*]] = and i64 [[X]], 15 168; CHECK-NEXT: br label [[END]] 169; CHECK: end: 170; CHECK-NEXT: [[X_MASK:%.*]] = phi i64 [ [[X]], [[ENTRY:%.*]] ], [ [[MASK]], [[BODY]] ] 171; CHECK-NEXT: [[RES:%.*]] = and i64 [[X_MASK]], 3 172; CHECK-NEXT: ret i64 [[RES]] 173; 174entry: 175 %cmp = icmp ule i64 %x, 15 176 br i1 %cmp, label %end, label %body 177body: 178 %mask = and i64 %x, 15 179 br label %end 180end: 181 %x.mask = phi i64 [ %x, %entry ], [ %mask, %body ] 182 %res = and i64 %x.mask, 3 183 ret i64 %res 184} 185 186; %x either ult 8 or is masked with 7 187define i64 @limit_i64_ult_8_mask1(i64 %x) { 188; CHECK-LABEL: @limit_i64_ult_8_mask1( 189; CHECK-NEXT: entry: 190; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[X:%.*]], 8 191; CHECK-NEXT: br i1 [[CMP]], label [[END:%.*]], label [[BODY:%.*]] 192; CHECK: body: 193; CHECK-NEXT: [[MASK:%.*]] = and i64 [[X]], 7 194; CHECK-NEXT: br label [[END]] 195; CHECK: end: 196; CHECK-NEXT: [[X_MASK:%.*]] = phi i64 [ [[X]], [[ENTRY:%.*]] ], [ [[MASK]], [[BODY]] ] 197; CHECK-NEXT: [[RES:%.*]] = and i64 [[X_MASK]], 1 198; CHECK-NEXT: ret i64 [[RES]] 199; 200entry: 201 %cmp = icmp ult i64 %x, 8 202 br i1 %cmp, label %end, label %body 203body: 204 %mask = and i64 %x, 7 205 br label %end 206end: 207 %x.mask = phi i64 [ %x, %entry ], [ %mask, %body ] 208 %res = and i64 %x.mask, 1 209 ret i64 %res 210} 211