1; RUN: opt -instcombine -S -o - %s | FileCheck %s 2 3define i1 @masked_and_notallzeroes(i32 %A) { 4; CHECK-LABEL: @masked_and_notallzeroes 5; CHECK: [[MASK:%.*]] = and i32 %A, 7 6; CHECK: icmp ne i32 [[MASK]], 0 7; CHECK-NOT: and i32 %A, 39 8; CHECK: ret i1 9 10 %mask1 = and i32 %A, 7 11 %tst1 = icmp ne i32 %mask1, 0 12 13 %mask2 = and i32 %A, 39 14 %tst2 = icmp ne i32 %mask2, 0 15 16 %res = and i1 %tst1, %tst2 17 ret i1 %res 18} 19 20define i1 @masked_or_allzeroes(i32 %A) { 21; CHECK-LABEL: @masked_or_allzeroes 22; CHECK: [[MASK:%.*]] = and i32 %A, 7 23; CHECK: icmp eq i32 [[MASK]], 0 24; CHECK-NOT: and i32 %A, 39 25; CHECK: ret i1 26 27 %mask1 = and i32 %A, 7 28 %tst1 = icmp eq i32 %mask1, 0 29 30 %mask2 = and i32 %A, 39 31 %tst2 = icmp eq i32 %mask2, 0 32 33 %res = or i1 %tst1, %tst2 34 ret i1 %res 35} 36 37define i1 @masked_and_notallones(i32 %A) { 38; CHECK-LABEL: @masked_and_notallones 39; CHECK: [[MASK:%.*]] = and i32 %A, 7 40; CHECK: icmp ne i32 [[MASK]], 7 41; CHECK-NOT: and i32 %A, 39 42; CHECK: ret i1 43 44 %mask1 = and i32 %A, 7 45 %tst1 = icmp ne i32 %mask1, 7 46 47 %mask2 = and i32 %A, 39 48 %tst2 = icmp ne i32 %mask2, 39 49 50 %res = and i1 %tst1, %tst2 51 ret i1 %res 52} 53 54define i1 @masked_or_allones(i32 %A) { 55; CHECK-LABEL: @masked_or_allones 56; CHECK: [[MASK:%.*]] = and i32 %A, 7 57; CHECK: icmp eq i32 [[MASK]], 7 58; CHECK-NOT: and i32 %A, 39 59; CHECK: ret i1 60 61 %mask1 = and i32 %A, 7 62 %tst1 = icmp eq i32 %mask1, 7 63 64 %mask2 = and i32 %A, 39 65 %tst2 = icmp eq i32 %mask2, 39 66 67 %res = or i1 %tst1, %tst2 68 ret i1 %res 69} 70 71define i1 @masked_and_notA(i32 %A) { 72; CHECK-LABEL: @masked_and_notA 73; CHECK: [[MASK:%.*]] = and i32 %A, 39 74; CHECK: icmp ne i32 [[MASK]], %A 75; CHECK-NOT: and i32 %A, 7 76; CHECK: ret i1 77 78 %mask1 = and i32 %A, 7 79 %tst1 = icmp ne i32 %mask1, %A 80 81 %mask2 = and i32 %A, 39 82 %tst2 = icmp ne i32 %mask2, %A 83 84 %res = and i1 %tst1, %tst2 85 ret i1 %res 86} 87 88define i1 @masked_or_A(i32 %A) { 89; CHECK-LABEL: @masked_or_A 90; CHECK: [[MASK:%.*]] = and i32 %A, 39 91; CHECK: icmp eq i32 [[MASK]], %A 92; CHECK-NOT: and i32 %A, 7 93; CHECK: ret i1 94 95 %mask1 = and i32 %A, 7 96 %tst1 = icmp eq i32 %mask1, %A 97 98 %mask2 = and i32 %A, 39 99 %tst2 = icmp eq i32 %mask2, %A 100 101 %res = or i1 %tst1, %tst2 102 ret i1 %res 103} 104 105define i1 @masked_or_allzeroes_notoptimised(i32 %A) { 106; CHECK-LABEL: @masked_or_allzeroes_notoptimised 107; CHECK: [[MASK:%.*]] = and i32 %A, 15 108; CHECK: icmp eq i32 [[MASK]], 0 109; CHECK: [[MASK:%.*]] = and i32 %A, 39 110; CHECK: icmp eq i32 [[MASK]], 0 111; CHECK: ret i1 112 113 %mask1 = and i32 %A, 15 114 %tst1 = icmp eq i32 %mask1, 0 115 116 %mask2 = and i32 %A, 39 117 %tst2 = icmp eq i32 %mask2, 0 118 119 %res = or i1 %tst1, %tst2 120 ret i1 %res 121} 122 123define i1 @nomask_lhs(i32 %in) { 124; CHECK-LABEL: @nomask_lhs 125; CHECK: [[MASK:%.*]] = and i32 %in, 1 126; CHECK: icmp eq i32 [[MASK]], 0 127; CHECK-NOT: icmp 128; CHECK: ret i1 129 %tst1 = icmp eq i32 %in, 0 130 131 %masked = and i32 %in, 1 132 %tst2 = icmp eq i32 %masked, 0 133 134 %val = or i1 %tst1, %tst2 135 ret i1 %val 136} 137 138 139define i1 @nomask_rhs(i32 %in) { 140; CHECK-LABEL: @nomask_rhs 141; CHECK: [[MASK:%.*]] = and i32 %in, 1 142; CHECK: icmp eq i32 [[MASK]], 0 143; CHECK-NOT: icmp 144; CHECK: ret i1 145 %masked = and i32 %in, 1 146 %tst1 = icmp eq i32 %masked, 0 147 148 %tst2 = icmp eq i32 %in, 0 149 150 %val = or i1 %tst1, %tst2 151 ret i1 %val 152} 153 154define i1 @fold_mask_cmps_to_false(i32 %x) { 155; CHECK-LABEL: @fold_mask_cmps_to_false 156; CHECK: ret i1 false 157 %1 = and i32 %x, 2147483647 158 %2 = icmp eq i32 %1, 0 159 %3 = icmp eq i32 %x, 2147483647 160 %4 = and i1 %3, %2 161 ret i1 %4 162} 163 164define i1 @fold_mask_cmps_to_true(i32 %x) { 165; CHECK-LABEL: @fold_mask_cmps_to_true 166; CHECK: ret i1 true 167 %1 = and i32 %x, 2147483647 168 %2 = icmp ne i32 %1, 0 169 %3 = icmp ne i32 %x, 2147483647 170 %4 = or i1 %3, %2 171 ret i1 %4 172} 173