1 ; RUN: opt -instcombine -S -o - %s | FileCheck %s 2 3 define 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 20 define 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 37 define 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 54 define 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 71 define 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 88 define 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 105 define 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 123 define 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 139 define 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 154 define 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 164 define 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