1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 4declare i1 @barrier() 5declare void @llvm.assume(i1) 6declare void @use.i8(i8) 7 8define i1 @icmp_ult_x_y(i8 %x, i8 %y) { 9; CHECK-LABEL: @icmp_ult_x_y( 10; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], [[Y:%.*]] 11; CHECK-NEXT: [[Z:%.*]] = icmp ne i8 [[AND]], [[X]] 12; CHECK-NEXT: ret i1 [[Z]] 13; 14 %and = and i8 %x, %y 15 %z = icmp ult i8 %and, %x 16 ret i1 %z 17} 18 19define i1 @icmp_ult_x_y_2(i8 %xx, i8 %y) { 20; CHECK-LABEL: @icmp_ult_x_y_2( 21; CHECK-NEXT: [[X:%.*]] = mul i8 [[XX:%.*]], [[XX]] 22; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], [[Y:%.*]] 23; CHECK-NEXT: [[Z:%.*]] = icmp ne i8 [[AND]], [[X]] 24; CHECK-NEXT: ret i1 [[Z]] 25; 26 %x = mul i8 %xx, %xx 27 %and = and i8 %x, %y 28 %z = icmp ugt i8 %x, %and 29 ret i1 %z 30} 31 32define <2 x i1> @icmp_uge_x_y(<2 x i8> %x, <2 x i8> %y) { 33; CHECK-LABEL: @icmp_uge_x_y( 34; CHECK-NEXT: [[AND:%.*]] = and <2 x i8> [[X:%.*]], [[Y:%.*]] 35; CHECK-NEXT: [[Z:%.*]] = icmp eq <2 x i8> [[AND]], [[X]] 36; CHECK-NEXT: ret <2 x i1> [[Z]] 37; 38 %and = and <2 x i8> %x, %y 39 %z = icmp uge <2 x i8> %and, %x 40 ret <2 x i1> %z 41} 42 43define i1 @icmp_uge_x_y_2(i8 %xx, i8 %y) { 44; CHECK-LABEL: @icmp_uge_x_y_2( 45; CHECK-NEXT: [[X:%.*]] = mul i8 [[XX:%.*]], [[XX]] 46; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], [[Y:%.*]] 47; CHECK-NEXT: [[Z:%.*]] = icmp eq i8 [[AND]], [[X]] 48; CHECK-NEXT: ret i1 [[Z]] 49; 50 %x = mul i8 %xx, %xx 51 %and = and i8 %x, %y 52 %z = icmp ule i8 %x, %and 53 ret i1 %z 54} 55 56define i1 @icmp_sge_x_negy(i8 %x, i8 %y) { 57; CHECK-LABEL: @icmp_sge_x_negy( 58; CHECK-NEXT: [[CY:%.*]] = icmp slt i8 [[Y:%.*]], 0 59; CHECK-NEXT: call void @llvm.assume(i1 [[CY]]) 60; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], [[Y]] 61; CHECK-NEXT: [[Z:%.*]] = icmp eq i8 [[AND]], [[X]] 62; CHECK-NEXT: ret i1 [[Z]] 63; 64 %cy = icmp slt i8 %y, 0 65 call void @llvm.assume(i1 %cy) 66 %and = and i8 %x, %y 67 %z = icmp sge i8 %and, %x 68 ret i1 %z 69} 70 71define i1 @icmp_slt_x_negy(i8 %x, i8 %y) { 72; CHECK-LABEL: @icmp_slt_x_negy( 73; CHECK-NEXT: [[CY:%.*]] = icmp slt i8 [[Y:%.*]], 0 74; CHECK-NEXT: br i1 [[CY]], label [[NEGY:%.*]], label [[POSY:%.*]] 75; CHECK: negy: 76; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], [[Y]] 77; CHECK-NEXT: [[Z:%.*]] = icmp ne i8 [[AND]], [[X]] 78; CHECK-NEXT: ret i1 [[Z]] 79; CHECK: posy: 80; CHECK-NEXT: [[R:%.*]] = call i1 @barrier() 81; CHECK-NEXT: ret i1 [[R]] 82; 83 %cy = icmp slt i8 %y, 0 84 br i1 %cy, label %negy, label %posy 85negy: 86 %and = and i8 %x, %y 87 %z = icmp slt i8 %and, %x 88 ret i1 %z 89posy: 90 %r = call i1 @barrier() 91 ret i1 %r 92} 93 94define i1 @icmp_slt_x_negy_fail_maybe_zero(i8 %x, i8 %y) { 95; CHECK-LABEL: @icmp_slt_x_negy_fail_maybe_zero( 96; CHECK-NEXT: [[CY:%.*]] = icmp slt i8 [[Y:%.*]], 1 97; CHECK-NEXT: br i1 [[CY]], label [[NEGY:%.*]], label [[POSY:%.*]] 98; CHECK: negy: 99; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], [[Y]] 100; CHECK-NEXT: [[Z:%.*]] = icmp slt i8 [[AND]], [[X]] 101; CHECK-NEXT: ret i1 [[Z]] 102; CHECK: posy: 103; CHECK-NEXT: [[R:%.*]] = call i1 @barrier() 104; CHECK-NEXT: ret i1 [[R]] 105; 106 %cy = icmp sle i8 %y, 0 107 br i1 %cy, label %negy, label %posy 108negy: 109 %and = and i8 %x, %y 110 %z = icmp slt i8 %and, %x 111 ret i1 %z 112posy: 113 %r = call i1 @barrier() 114 ret i1 %r 115} 116 117define i1 @icmp_sle_x_negy(i8 %x, i8 %yy) { 118; CHECK-LABEL: @icmp_sle_x_negy( 119; CHECK-NEXT: ret i1 true 120; 121 %y = or i8 %yy, 128 122 %and = and i8 %y, %x 123 %z = icmp sle i8 %and, %x 124 ret i1 %z 125} 126 127define <2 x i1> @icmp_sgt_x_negy(<2 x i8> %x, <2 x i8> %yy) { 128; CHECK-LABEL: @icmp_sgt_x_negy( 129; CHECK-NEXT: ret <2 x i1> zeroinitializer 130; 131 %y = or <2 x i8> %yy, <i8 128, i8 128> 132 %and = and <2 x i8> %y, %x 133 %z = icmp sgt <2 x i8> %and, %x 134 ret <2 x i1> %z 135} 136 137define <2 x i1> @icmp_sgt_x_negy_fail_partial(<2 x i8> %x, <2 x i8> %yy) { 138; CHECK-LABEL: @icmp_sgt_x_negy_fail_partial( 139; CHECK-NEXT: [[Y:%.*]] = or <2 x i8> [[YY:%.*]], <i8 -128, i8 4> 140; CHECK-NEXT: [[AND:%.*]] = and <2 x i8> [[Y]], [[X:%.*]] 141; CHECK-NEXT: [[Z:%.*]] = icmp sgt <2 x i8> [[AND]], [[X]] 142; CHECK-NEXT: ret <2 x i1> [[Z]] 143; 144 %y = or <2 x i8> %yy, <i8 128, i8 4> 145 %and = and <2 x i8> %y, %x 146 %z = icmp sgt <2 x i8> %and, %x 147 ret <2 x i1> %z 148} 149 150define <2 x i1> @icmp_sle_x_posy(<2 x i8> %x, <2 x i8> %yy) { 151; CHECK-LABEL: @icmp_sle_x_posy( 152; CHECK-NEXT: [[Z:%.*]] = icmp sgt <2 x i8> [[X:%.*]], splat (i8 -1) 153; CHECK-NEXT: ret <2 x i1> [[Z]] 154; 155 %y = and <2 x i8> %yy, <i8 127, i8 127> 156 %and = and <2 x i8> %y, %x 157 %z = icmp sle <2 x i8> %and, %x 158 ret <2 x i1> %z 159} 160 161define <2 x i1> @icmp_sle_x_posy_fail_partial(<2 x i8> %x, <2 x i8> %yy) { 162; CHECK-LABEL: @icmp_sle_x_posy_fail_partial( 163; CHECK-NEXT: [[Y:%.*]] = and <2 x i8> [[YY:%.*]], <i8 127, i8 -65> 164; CHECK-NEXT: [[AND:%.*]] = and <2 x i8> [[Y]], [[X:%.*]] 165; CHECK-NEXT: [[Z:%.*]] = icmp sle <2 x i8> [[AND]], [[X]] 166; CHECK-NEXT: ret <2 x i1> [[Z]] 167; 168 %y = and <2 x i8> %yy, <i8 127, i8 191> 169 %and = and <2 x i8> %y, %x 170 %z = icmp sle <2 x i8> %and, %x 171 ret <2 x i1> %z 172} 173 174define i1 @icmp_sgt_x_posy(i8 %x, i8 %y) { 175; CHECK-LABEL: @icmp_sgt_x_posy( 176; CHECK-NEXT: [[CY:%.*]] = icmp sgt i8 [[Y:%.*]], -1 177; CHECK-NEXT: call void @llvm.assume(i1 [[CY]]) 178; CHECK-NEXT: [[Z:%.*]] = icmp slt i8 [[X:%.*]], 0 179; CHECK-NEXT: ret i1 [[Z]] 180; 181 %cy = icmp sge i8 %y, 0 182 call void @llvm.assume(i1 %cy) 183 %and = and i8 %x, %y 184 %z = icmp sgt i8 %and, %x 185 ret i1 %z 186} 187 188define <2 x i1> @icmp_sgt_negx_y(<2 x i8> %xx, <2 x i8> %y) { 189; CHECK-LABEL: @icmp_sgt_negx_y( 190; CHECK-NEXT: [[Z:%.*]] = icmp sgt <2 x i8> [[Y:%.*]], splat (i8 -1) 191; CHECK-NEXT: ret <2 x i1> [[Z]] 192; 193 %x = or <2 x i8> %xx, <i8 128, i8 128> 194 %and = and <2 x i8> %x, %y 195 %z = icmp sgt <2 x i8> %and, %x 196 ret <2 x i1> %z 197} 198 199define i1 @icmp_sle_negx_y(i8 %x, i8 %y) { 200; CHECK-LABEL: @icmp_sle_negx_y( 201; CHECK-NEXT: [[CX:%.*]] = icmp slt i8 [[X:%.*]], 0 202; CHECK-NEXT: call void @llvm.assume(i1 [[CX]]) 203; CHECK-NEXT: [[Z:%.*]] = icmp slt i8 [[Y:%.*]], 0 204; CHECK-NEXT: ret i1 [[Z]] 205; 206 %cx = icmp slt i8 %x, 0 207 call void @llvm.assume(i1 %cx) 208 %and = and i8 %x, %y 209 %z = icmp sle i8 %and, %x 210 ret i1 %z 211} 212 213define i1 @icmp_sle_negx_y_fail_maybe_zero(i8 %x, i8 %y) { 214; CHECK-LABEL: @icmp_sle_negx_y_fail_maybe_zero( 215; CHECK-NEXT: [[CX:%.*]] = icmp slt i8 [[X:%.*]], 1 216; CHECK-NEXT: call void @llvm.assume(i1 [[CX]]) 217; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], [[Y:%.*]] 218; CHECK-NEXT: [[Z:%.*]] = icmp sle i8 [[AND]], [[X]] 219; CHECK-NEXT: ret i1 [[Z]] 220; 221 %cx = icmp sle i8 %x, 0 222 call void @llvm.assume(i1 %cx) 223 %and = and i8 %x, %y 224 %z = icmp sle i8 %and, %x 225 ret i1 %z 226} 227 228define i1 @icmp_eq_x_invertable_y_todo(i8 %x, i1 %y) { 229; CHECK-LABEL: @icmp_eq_x_invertable_y_todo( 230; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[Y:%.*]], i8 -8, i8 -25 231; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[X:%.*]], [[TMP1]] 232; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[TMP2]], 0 233; CHECK-NEXT: ret i1 [[R]] 234; 235 %yy = select i1 %y, i8 7, i8 24 236 %and = and i8 %x, %yy 237 %r = icmp eq i8 %x, %and 238 ret i1 %r 239} 240 241define i1 @icmp_eq_x_invertable_y(i8 %x, i8 %y) { 242; CHECK-LABEL: @icmp_eq_x_invertable_y( 243; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], [[Y:%.*]] 244; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[TMP1]], 0 245; CHECK-NEXT: ret i1 [[R]] 246; 247 %yy = xor i8 %y, -1 248 %and = and i8 %x, %yy 249 %r = icmp eq i8 %x, %and 250 ret i1 %r 251} 252 253define i1 @icmp_eq_x_invertable_y_fail_multiuse(i8 %x, i8 %y) { 254; CHECK-LABEL: @icmp_eq_x_invertable_y_fail_multiuse( 255; CHECK-NEXT: [[YY:%.*]] = xor i8 [[Y:%.*]], -1 256; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], [[YY]] 257; CHECK-NEXT: call void @use.i8(i8 [[AND]]) 258; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[X]], [[AND]] 259; CHECK-NEXT: ret i1 [[R]] 260; 261 %yy = xor i8 %y, -1 262 %and = and i8 %x, %yy 263 call void @use.i8(i8 %and) 264 %r = icmp eq i8 %x, %and 265 ret i1 %r 266} 267 268define i1 @icmp_eq_x_invertable_y2_todo(i8 %x, i1 %y) { 269; CHECK-LABEL: @icmp_eq_x_invertable_y2_todo( 270; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[Y:%.*]], i8 -8, i8 -25 271; CHECK-NEXT: [[TMP2:%.*]] = or i8 [[X:%.*]], [[TMP1]] 272; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[TMP2]], -1 273; CHECK-NEXT: ret i1 [[R]] 274; 275 %yy = select i1 %y, i8 7, i8 24 276 %and = and i8 %x, %yy 277 %r = icmp eq i8 %yy, %and 278 ret i1 %r 279} 280 281define i1 @icmp_eq_x_invertable_y2(i8 %x, i8 %y) { 282; CHECK-LABEL: @icmp_eq_x_invertable_y2( 283; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[X:%.*]], [[Y:%.*]] 284; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[TMP1]], -1 285; CHECK-NEXT: ret i1 [[R]] 286; 287 %yy = xor i8 %y, -1 288 %and = and i8 %x, %yy 289 %r = icmp eq i8 %yy, %and 290 ret i1 %r 291} 292 293define i1 @icmp_eq_x_invertable_y_fail_immconstant(i8 %x, i8 %y) { 294; CHECK-LABEL: @icmp_eq_x_invertable_y_fail_immconstant( 295; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 7 296; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[AND]], 7 297; CHECK-NEXT: ret i1 [[R]] 298; 299 %and = and i8 %x, 7 300 %r = icmp eq i8 %and, 7 301 ret i1 %r 302} 303