1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -S -passes=instcombine < %s | FileCheck %s 3 4declare void @llvm.assume(i1) 5 6define i1 @blsmsk_eq_is_false(i32 %x) { 7; CHECK-LABEL: @blsmsk_eq_is_false( 8; CHECK-NEXT: ret i1 false 9; 10 %x1 = or i32 %x, 10 11 %x2 = sub i32 %x1, 1 12 %x3 = xor i32 %x1, %x2 13 %z = icmp eq i32 %x3, 8 14 ret i1 %z 15} 16 17define <2 x i1> @blsmsk_ne_is_true_vec(<2 x i32> %x) { 18; CHECK-LABEL: @blsmsk_ne_is_true_vec( 19; CHECK-NEXT: ret <2 x i1> splat (i1 true) 20; 21 %x1 = or <2 x i32> %x, <i32 10, i32 10> 22 %x2 = sub <2 x i32> %x1, <i32 1, i32 1> 23 %x3 = xor <2 x i32> %x2, %x1 24 %z = icmp ne <2 x i32> %x3, <i32 8, i32 8> 25 ret <2 x i1> %z 26} 27 28define <2 x i1> @blsmsk_ne_is_true_diff_vec(<2 x i32> %x) { 29; CHECK-LABEL: @blsmsk_ne_is_true_diff_vec( 30; CHECK-NEXT: ret <2 x i1> splat (i1 true) 31; 32 %x1 = or <2 x i32> %x, <i32 10, i32 130> 33 %x2 = sub <2 x i32> %x1, <i32 1, i32 1> 34 %x3 = xor <2 x i32> %x2, %x1 35 %z = icmp ne <2 x i32> %x3, <i32 8, i32 8> 36 ret <2 x i1> %z 37} 38 39define i1 @blsmsk_ge_is_false(i32 %x) { 40; CHECK-LABEL: @blsmsk_ge_is_false( 41; CHECK-NEXT: ret i1 false 42; 43 %x1 = or i32 %x, 10 44 %x2 = sub i32 %x1, 1 45 %x3 = xor i32 %x1, %x2 46 %z = icmp uge i32 %x3, 8 47 ret i1 %z 48} 49 50define <2 x i1> @blsmsk_gt_is_false_vec(<2 x i32> %x) { 51; CHECK-LABEL: @blsmsk_gt_is_false_vec( 52; CHECK-NEXT: ret <2 x i1> zeroinitializer 53; 54 %x1 = or <2 x i32> %x, <i32 10, i32 10> 55 %x2 = sub <2 x i32> %x1, <i32 1, i32 1> 56 %x3 = xor <2 x i32> %x2, %x1 57 %z = icmp ugt <2 x i32> %x3, <i32 8, i32 8> 58 ret <2 x i1> %z 59} 60 61define i1 @blsmsk_signed_is_false(i32 %x) { 62; CHECK-LABEL: @blsmsk_signed_is_false( 63; CHECK-NEXT: ret i1 false 64; 65 %x1 = or i32 %x, 10 66 %x2 = sub i32 %x1, 1 67 %x3 = xor i32 %x1, %x2 68 %z = icmp slt i32 %x3, 0 69 ret i1 %z 70} 71 72define i32 @blsmsk_add_eval(i32 %x) { 73; CHECK-LABEL: @blsmsk_add_eval( 74; CHECK-NEXT: ret i32 33 75; 76 %x1 = or i32 %x, 9 77 %x2 = sub i32 %x1, 1 78 %x3 = xor i32 %x2, %x1 79 %z = add i32 %x3, 32 80 ret i32 %z 81} 82 83define <2 x i32> @blsmsk_add_eval_vec(<2 x i32> %x) { 84; CHECK-LABEL: @blsmsk_add_eval_vec( 85; CHECK-NEXT: ret <2 x i32> splat (i32 33) 86; 87 %x1 = or <2 x i32> %x, <i32 9, i32 9> 88 %x2 = add <2 x i32> %x1, <i32 -1, i32 -1> 89 %x3 = xor <2 x i32> %x2, %x1 90 %z = add <2 x i32> %x3, <i32 32, i32 32> 91 ret <2 x i32> %z 92} 93 94define i32 @blsmsk_sub_eval(i32 %x) { 95; CHECK-LABEL: @blsmsk_sub_eval( 96; CHECK-NEXT: ret i32 -31 97; 98 %x1 = or i32 %x, 9 99 %x2 = sub i32 %x1, 1 100 %x3 = xor i32 %x1, %x2 101 %z = sub i32 %x3, 32 102 ret i32 %z 103} 104 105define i32 @blsmsk_or_eval(i32 %x) { 106; CHECK-LABEL: @blsmsk_or_eval( 107; CHECK-NEXT: ret i32 33 108; 109 %x1 = or i32 %x, 129 110 %x2 = sub i32 %x1, 1 111 %x3 = xor i32 %x2, %x1 112 %z = or i32 %x3, 32 113 ret i32 %z 114} 115 116define <2 x i32> @blsmsk_or_eval_vec(<2 x i32> %x) { 117; CHECK-LABEL: @blsmsk_or_eval_vec( 118; CHECK-NEXT: ret <2 x i32> splat (i32 33) 119; 120 %x1 = or <2 x i32> %x, <i32 9, i32 9> 121 %x2 = add <2 x i32> %x1, <i32 -1, i32 -1> 122 %x3 = xor <2 x i32> %x2, %x1 123 %z = or <2 x i32> %x3, <i32 32, i32 32> 124 ret <2 x i32> %z 125} 126 127define i32 @blsmsk_xor_eval(i32 %x) { 128; CHECK-LABEL: @blsmsk_xor_eval( 129; CHECK-NEXT: ret i32 33 130; 131 %x1 = or i32 %x, 255 132 %x2 = sub i32 %x1, 1 133 %x3 = xor i32 %x1, %x2 134 %z = xor i32 %x3, 32 135 ret i32 %z 136} 137 138define i32 @blsmsk_and_eval(i32 %x) { 139; CHECK-LABEL: @blsmsk_and_eval( 140; CHECK-NEXT: ret i32 0 141; 142 %x1 = or i32 %x, 34 143 %x2 = sub i32 %x1, 1 144 %x3 = xor i32 %x2, %x1 145 %z = and i32 %x3, 32 146 ret i32 %z 147} 148 149define <2 x i32> @blsmsk_and_eval_vec(<2 x i32> %x) { 150; CHECK-LABEL: @blsmsk_and_eval_vec( 151; CHECK-NEXT: ret <2 x i32> zeroinitializer 152; 153 %x1 = or <2 x i32> %x, <i32 34, i32 34> 154 %x2 = add <2 x i32> %x1, <i32 -1, i32 -1> 155 %x3 = xor <2 x i32> %x2, %x1 156 %z = and <2 x i32> %x3, <i32 32, i32 32> 157 ret <2 x i32> %z 158} 159 160define i32 @blsmsk_and_eval2(i32 %x) { 161; CHECK-LABEL: @blsmsk_and_eval2( 162; CHECK-NEXT: [[X1:%.*]] = or i32 [[X:%.*]], 10 163; CHECK-NEXT: [[X2:%.*]] = add i32 [[X1]], 63 164; CHECK-NEXT: [[X3:%.*]] = xor i32 [[X]], [[X2]] 165; CHECK-NEXT: [[Z:%.*]] = and i32 [[X3]], 32 166; CHECK-NEXT: ret i32 [[Z]] 167; 168 %x1 = or i32 %x, 10 169 %x2 = sub i32 %x1, 1 170 %x3 = xor i32 %x1, %x2 171 %z = and i32 %x3, 32 172 ret i32 %z 173} 174 175define <2 x i32> @blsmsk_and_eval3_vec(<2 x i32> %x) { 176; CHECK-LABEL: @blsmsk_and_eval3_vec( 177; CHECK-NEXT: [[X1:%.*]] = or <2 x i32> [[X:%.*]], splat (i32 34) 178; CHECK-NEXT: [[X2:%.*]] = add <2 x i32> [[X1]], splat (i32 63) 179; CHECK-NEXT: [[X3:%.*]] = xor <2 x i32> [[X2]], [[X1]] 180; CHECK-NEXT: [[Z:%.*]] = and <2 x i32> [[X3]], <i32 16, i32 32> 181; CHECK-NEXT: ret <2 x i32> [[Z]] 182; 183 %x1 = or <2 x i32> %x, <i32 34, i32 34> 184 %x2 = add <2 x i32> %x1, <i32 -1, i32 -1> 185 %x3 = xor <2 x i32> %x2, %x1 186 %z = and <2 x i32> %x3, <i32 16, i32 32> 187 ret <2 x i32> %z 188} 189 190define i1 @blsmsk_eq_is_false_assume(i32 %x) { 191; CHECK-LABEL: @blsmsk_eq_is_false_assume( 192; CHECK-NEXT: [[LB:%.*]] = and i32 [[X:%.*]], 4 193; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[LB]], 0 194; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) 195; CHECK-NEXT: ret i1 false 196; 197 %lb = and i32 %x, 4 198 %cmp = icmp ne i32 %lb, 0 199 call void @llvm.assume(i1 %cmp) 200 %x2 = add i32 %x, -1 201 %x3 = xor i32 %x2, %x 202 %z = icmp eq i32 %x3, 8 203 ret i1 %z 204} 205 206define i1 @blsmsk_gt_is_false_assume(i32 %x) { 207; CHECK-LABEL: @blsmsk_gt_is_false_assume( 208; CHECK-NEXT: [[LB:%.*]] = and i32 [[X:%.*]], 2 209; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[LB]], 0 210; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) 211; CHECK-NEXT: ret i1 false 212; 213 %lb = and i32 %x, 2 214 %cmp = icmp ne i32 %lb, 0 215 call void @llvm.assume(i1 %cmp) 216 %x2 = sub i32 %x, 1 217 %x3 = xor i32 %x2, %x 218 %z = icmp ugt i32 %x3, 8 219 ret i1 %z 220} 221 222define i32 @blsmsk_add_eval_assume(i32 %x) { 223; CHECK-LABEL: @blsmsk_add_eval_assume( 224; CHECK-NEXT: [[LB:%.*]] = and i32 [[X:%.*]], 1 225; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[LB]], 0 226; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) 227; CHECK-NEXT: ret i32 33 228; 229 %lb = and i32 %x, 1 230 %cmp = icmp ne i32 %lb, 0 231 call void @llvm.assume(i1 %cmp) 232 %x2 = sub i32 %x, 1 233 %x3 = xor i32 %x2, %x 234 %z = add i32 %x3, 32 235 ret i32 %z 236} 237 238define <2 x i32> @blsmsk_add_eval_assume_vec(<2 x i32> %x) { 239; CHECK-LABEL: @blsmsk_add_eval_assume_vec( 240; CHECK-NEXT: [[CMP:%.*]] = trunc <2 x i32> [[X:%.*]] to <2 x i1> 241; CHECK-NEXT: [[CMP0:%.*]] = extractelement <2 x i1> [[CMP]], i64 0 242; CHECK-NEXT: call void @llvm.assume(i1 [[CMP0]]) 243; CHECK-NEXT: [[CMP1:%.*]] = extractelement <2 x i1> [[CMP]], i64 1 244; CHECK-NEXT: call void @llvm.assume(i1 [[CMP1]]) 245; CHECK-NEXT: [[X2:%.*]] = add <2 x i32> [[X]], splat (i32 -1) 246; CHECK-NEXT: [[X3:%.*]] = xor <2 x i32> [[X2]], [[X]] 247; CHECK-NEXT: [[Z:%.*]] = add <2 x i32> [[X3]], splat (i32 32) 248; CHECK-NEXT: ret <2 x i32> [[Z]] 249; 250 %lb = and <2 x i32> %x, <i32 1, i32 1> 251 %cmp = icmp ne <2 x i32> %lb, <i32 0, i32 0> 252 %cmp0 = extractelement <2 x i1> %cmp, i32 0 253 call void @llvm.assume(i1 %cmp0) 254 %cmp1 = extractelement <2 x i1> %cmp, i32 1 255 call void @llvm.assume(i1 %cmp1) 256 %x2 = sub <2 x i32> %x, <i32 1, i32 1> 257 %x3 = xor <2 x i32> %x2, %x 258 %z = add <2 x i32> %x3, <i32 32, i32 32> 259 ret <2 x i32> %z 260} 261 262define i32 @blsmsk_sub_eval_assume(i32 %x) { 263; CHECK-LABEL: @blsmsk_sub_eval_assume( 264; CHECK-NEXT: [[LB:%.*]] = and i32 [[X:%.*]], 1 265; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[LB]], 0 266; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) 267; CHECK-NEXT: ret i32 -31 268; 269 %lb = and i32 %x, 1 270 %cmp = icmp ne i32 %lb, 0 271 call void @llvm.assume(i1 %cmp) 272 %x2 = sub i32 %x, 1 273 %x3 = xor i32 %x, %x2 274 %z = sub i32 %x3, 32 275 ret i32 %z 276} 277 278define i32 @blsmsk_or_eval_assume(i32 %x) { 279; CHECK-LABEL: @blsmsk_or_eval_assume( 280; CHECK-NEXT: [[LB:%.*]] = and i32 [[X:%.*]], 1 281; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[LB]], 0 282; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) 283; CHECK-NEXT: ret i32 33 284; 285 %lb = and i32 %x, 1 286 %cmp = icmp ne i32 %lb, 0 287 call void @llvm.assume(i1 %cmp) 288 %x2 = sub i32 %x, 1 289 %x3 = xor i32 %x2, %x 290 %z = or i32 %x3, 32 291 ret i32 %z 292} 293 294define i32 @blsmsk_and_eval_assume(i32 %x) { 295; CHECK-LABEL: @blsmsk_and_eval_assume( 296; CHECK-NEXT: [[LB:%.*]] = and i32 [[X:%.*]], 4 297; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[LB]], 0 298; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) 299; CHECK-NEXT: [[X2:%.*]] = add i32 [[X]], 63 300; CHECK-NEXT: [[X3:%.*]] = xor i32 [[X2]], [[X]] 301; CHECK-NEXT: [[Z:%.*]] = and i32 [[X3]], 32 302; CHECK-NEXT: ret i32 [[Z]] 303; 304 %lb = and i32 %x, 4 305 %cmp = icmp ne i32 %lb, 0 306 call void @llvm.assume(i1 %cmp) 307 %x2 = sub i32 %x, 1 308 %x3 = xor i32 %x2, %x 309 %z = and i32 %x3, 32 310 ret i32 %z 311} 312 313 314define <2 x i1> @blsi_eq_is_false_vec(<2 x i32> %x) { 315; CHECK-LABEL: @blsi_eq_is_false_vec( 316; CHECK-NEXT: ret <2 x i1> zeroinitializer 317; 318 %x1 = or <2 x i32> %x, <i32 10, i32 10> 319 %x2 = sub <2 x i32> <i32 0, i32 0>, %x1 320 %x3 = and <2 x i32> %x1, %x2 321 %z = icmp eq <2 x i32> %x3, <i32 8, i32 8> 322 ret <2 x i1> %z 323} 324 325define i1 @blsi_ne_is_true(i32 %x) { 326; CHECK-LABEL: @blsi_ne_is_true( 327; CHECK-NEXT: ret i1 true 328; 329 %x1 = or i32 %x, 10 330 %x2 = sub i32 0, %x1 331 %x3 = and i32 %x1, %x2 332 %z = icmp ne i32 %x3, 8 333 ret i1 %z 334} 335 336define <2 x i1> @blsi_ge_is_false_vec(<2 x i32> %x) { 337; CHECK-LABEL: @blsi_ge_is_false_vec( 338; CHECK-NEXT: [[X1:%.*]] = or <2 x i32> [[X:%.*]], splat (i32 10) 339; CHECK-NEXT: [[X2:%.*]] = sub nsw <2 x i32> zeroinitializer, [[X1]] 340; CHECK-NEXT: [[X3:%.*]] = and <2 x i32> [[X]], [[X2]] 341; CHECK-NEXT: [[Z:%.*]] = icmp ugt <2 x i32> [[X3]], splat (i32 7) 342; CHECK-NEXT: ret <2 x i1> [[Z]] 343; 344 %x1 = or <2 x i32> %x, <i32 10, i32 10> 345 %x2 = sub <2 x i32> <i32 0, i32 0>, %x1 346 %x3 = and <2 x i32> %x1, %x2 347 %z = icmp uge <2 x i32> %x3, <i32 8, i32 8> 348 ret <2 x i1> %z 349} 350 351define <2 x i1> @blsi_ge_is_false_diff_vec(<2 x i32> %x) { 352; CHECK-LABEL: @blsi_ge_is_false_diff_vec( 353; CHECK-NEXT: [[X1:%.*]] = or <2 x i32> [[X:%.*]], <i32 10, i32 11> 354; CHECK-NEXT: [[X2:%.*]] = sub nsw <2 x i32> zeroinitializer, [[X1]] 355; CHECK-NEXT: [[X3:%.*]] = and <2 x i32> [[X]], [[X2]] 356; CHECK-NEXT: [[Z:%.*]] = icmp ugt <2 x i32> [[X3]], splat (i32 7) 357; CHECK-NEXT: ret <2 x i1> [[Z]] 358; 359 %x1 = or <2 x i32> %x, <i32 10, i32 11> 360 %x2 = sub <2 x i32> <i32 0, i32 0>, %x1 361 %x3 = and <2 x i32> %x1, %x2 362 %z = icmp uge <2 x i32> %x3, <i32 8, i32 8> 363 ret <2 x i1> %z 364} 365 366define i1 @blsi_gt_is_false(i32 %x) { 367; CHECK-LABEL: @blsi_gt_is_false( 368; CHECK-NEXT: ret i1 false 369; 370 %x1 = or i32 %x, 10 371 %x2 = sub i32 0, %x1 372 %x3 = and i32 %x2, %x1 373 %z = icmp ugt i32 %x3, 8 374 ret i1 %z 375} 376 377 378define i32 @blsi_add_eval(i32 %x) { 379; CHECK-LABEL: @blsi_add_eval( 380; CHECK-NEXT: ret i32 33 381; 382 %x1 = or i32 %x, 9 383 %x2 = sub i32 0, %x1 384 %x3 = and i32 %x2, %x1 385 %z = add i32 %x3, 32 386 ret i32 %z 387} 388 389define i32 @blsi_sub_eval(i32 %x) { 390; CHECK-LABEL: @blsi_sub_eval( 391; CHECK-NEXT: ret i32 -31 392; 393 %x1 = or i32 %x, 33 394 %x2 = sub i32 0, %x1 395 %x3 = and i32 %x2, %x1 396 %z = sub i32 %x3, 32 397 ret i32 %z 398} 399 400define <2 x i32> @blsi_sub_eval_vec(<2 x i32> %x) { 401; CHECK-LABEL: @blsi_sub_eval_vec( 402; CHECK-NEXT: ret <2 x i32> splat (i32 -31) 403; 404 %x1 = or <2 x i32> %x, <i32 33, i32 33> 405 %x2 = sub <2 x i32> <i32 0, i32 0>, %x1 406 %x3 = and <2 x i32> %x1, %x2 407 %z = sub <2 x i32> %x3, <i32 32, i32 32> 408 ret <2 x i32> %z 409} 410 411define i32 @blsi_or_eval(i32 %x) { 412; CHECK-LABEL: @blsi_or_eval( 413; CHECK-NEXT: ret i32 33 414; 415 %x1 = or i32 %x, 129 416 %x2 = sub i32 0, %x1 417 %x3 = and i32 %x2, %x1 418 %z = or i32 %x3, 32 419 ret i32 %z 420} 421 422define <2 x i32> @blsi_xor_eval_vec(<2 x i32> %x) { 423; CHECK-LABEL: @blsi_xor_eval_vec( 424; CHECK-NEXT: ret <2 x i32> splat (i32 33) 425; 426 %x1 = or <2 x i32> %x, <i32 33, i32 33> 427 %x2 = sub <2 x i32> <i32 0, i32 0>, %x1 428 %x3 = and <2 x i32> %x2, %x1 429 %z = xor <2 x i32> %x3, <i32 32, i32 32> 430 ret <2 x i32> %z 431} 432 433define i32 @blsi_and_eval(i32 %x) { 434; CHECK-LABEL: @blsi_and_eval( 435; CHECK-NEXT: ret i32 0 436; 437 %x1 = or i32 %x, 34 438 %x2 = sub i32 0, %x1 439 %x3 = and i32 %x2, %x1 440 %z = and i32 %x3, 32 441 ret i32 %z 442} 443 444define <2 x i32> @blsi_and_eval2_vec(<2 x i32> %x) { 445; CHECK-LABEL: @blsi_and_eval2_vec( 446; CHECK-NEXT: [[X1:%.*]] = or <2 x i32> [[X:%.*]], splat (i32 30) 447; CHECK-NEXT: [[X2:%.*]] = sub nsw <2 x i32> zeroinitializer, [[X1]] 448; CHECK-NEXT: [[X3:%.*]] = and <2 x i32> [[X]], [[X2]] 449; CHECK-NEXT: [[Z:%.*]] = and <2 x i32> [[X3]], splat (i32 32) 450; CHECK-NEXT: ret <2 x i32> [[Z]] 451; 452 %x1 = or <2 x i32> %x, <i32 30, i32 30> 453 %x2 = sub <2 x i32> <i32 0, i32 0>, %x1 454 %x3 = and <2 x i32> %x1, %x2 455 %z = and <2 x i32> %x3, <i32 32, i32 32> 456 ret <2 x i32> %z 457} 458 459define i32 @blsi_and_eval3(i32 %x) { 460; CHECK-LABEL: @blsi_and_eval3( 461; CHECK-NEXT: [[X1:%.*]] = or i32 [[X:%.*]], 34 462; CHECK-NEXT: [[X2:%.*]] = sub nsw i32 0, [[X1]] 463; CHECK-NEXT: [[X3:%.*]] = and i32 [[X]], [[X2]] 464; CHECK-NEXT: [[Z:%.*]] = and i32 [[X3]], 208 465; CHECK-NEXT: ret i32 [[Z]] 466; 467 %x1 = or i32 %x, 34 468 %x2 = sub i32 0, %x1 469 %x3 = and i32 %x2, %x1 470 %z = and i32 %x3, 240 471 ret i32 %z 472} 473 474define <2 x i1> @blsi_eq_is_false_assume_vec(<2 x i32> %x) { 475; CHECK-LABEL: @blsi_eq_is_false_assume_vec( 476; CHECK-NEXT: [[LB:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 2) 477; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[LB]], zeroinitializer 478; CHECK-NEXT: [[CMP0:%.*]] = extractelement <2 x i1> [[CMP]], i64 0 479; CHECK-NEXT: call void @llvm.assume(i1 [[CMP0]]) 480; CHECK-NEXT: [[CMP1:%.*]] = extractelement <2 x i1> [[CMP]], i64 1 481; CHECK-NEXT: call void @llvm.assume(i1 [[CMP1]]) 482; CHECK-NEXT: [[X2:%.*]] = sub <2 x i32> zeroinitializer, [[X]] 483; CHECK-NEXT: [[X3:%.*]] = and <2 x i32> [[X]], [[X2]] 484; CHECK-NEXT: [[Z:%.*]] = icmp eq <2 x i32> [[X3]], splat (i32 8) 485; CHECK-NEXT: ret <2 x i1> [[Z]] 486; 487 %lb = and <2 x i32> %x, <i32 2, i32 2> 488 %cmp = icmp ne <2 x i32> %lb, <i32 0, i32 0> 489 %cmp0 = extractelement <2 x i1> %cmp, i32 0 490 call void @llvm.assume(i1 %cmp0) 491 %cmp1 = extractelement <2 x i1> %cmp, i32 1 492 call void @llvm.assume(i1 %cmp1) 493 %x2 = sub <2 x i32> <i32 0, i32 0>, %x 494 %x3 = and <2 x i32> %x2, %x 495 %z = icmp eq <2 x i32> %x3, <i32 8, i32 8> 496 ret <2 x i1> %z 497} 498 499define i1 @blsi_ne_is_true_assume(i32 %x) { 500; CHECK-LABEL: @blsi_ne_is_true_assume( 501; CHECK-NEXT: [[LB:%.*]] = and i32 [[X:%.*]], 4 502; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[LB]], 0 503; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) 504; CHECK-NEXT: ret i1 true 505; 506 %lb = and i32 %x, 4 507 %cmp = icmp ne i32 %lb, 0 508 call void @llvm.assume(i1 %cmp) 509 %x2 = sub i32 0, %x 510 %x3 = and i32 %x2, %x 511 %z = icmp ne i32 %x3, 8 512 ret i1 %z 513} 514 515define i1 @blsi_ge_is_false_assume(i32 %x) { 516; CHECK-LABEL: @blsi_ge_is_false_assume( 517; CHECK-NEXT: [[LB:%.*]] = and i32 [[X:%.*]], 4 518; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[LB]], 0 519; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) 520; CHECK-NEXT: ret i1 false 521; 522 %lb = and i32 %x, 4 523 %cmp = icmp ne i32 %lb, 0 524 call void @llvm.assume(i1 %cmp) 525 %x2 = sub i32 0, %x 526 %x3 = and i32 %x2, %x 527 %z = icmp uge i32 %x3, 8 528 ret i1 %z 529} 530 531define <2 x i1> @blsi_cmp_eq_diff_bits_vec(<2 x i32> %x) { 532; CHECK-LABEL: @blsi_cmp_eq_diff_bits_vec( 533; CHECK-NEXT: [[X1:%.*]] = or <2 x i32> [[X:%.*]], <i32 1, i32 2> 534; CHECK-NEXT: [[X2:%.*]] = sub <2 x i32> zeroinitializer, [[X1]] 535; CHECK-NEXT: [[X3:%.*]] = and <2 x i32> [[X1]], [[X2]] 536; CHECK-NEXT: [[Z:%.*]] = icmp eq <2 x i32> [[X3]], splat (i32 32) 537; CHECK-NEXT: ret <2 x i1> [[Z]] 538; 539 %x1 = or <2 x i32> %x, <i32 1, i32 2> 540 %x2 = sub <2 x i32> <i32 0, i32 0>, %x1 541 %x3 = and <2 x i32> %x1, %x2 542 %z = icmp eq <2 x i32> %x3, <i32 32, i32 32> 543 ret <2 x i1> %z 544} 545 546define i32 @blsi_xor_eval_assume(i32 %x) { 547; CHECK-LABEL: @blsi_xor_eval_assume( 548; CHECK-NEXT: [[LB:%.*]] = and i32 [[X:%.*]], 1 549; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[LB]], 0 550; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) 551; CHECK-NEXT: ret i32 33 552; 553 %lb = and i32 %x, 1 554 %cmp = icmp ne i32 %lb, 0 555 call void @llvm.assume(i1 %cmp) 556 %x2 = sub i32 0, %x 557 %x3 = and i32 %x2, %x 558 %z = xor i32 %x3, 32 559 ret i32 %z 560} 561 562define i32 @blsi_and_eval_assume(i32 %x) { 563; CHECK-LABEL: @blsi_and_eval_assume( 564; CHECK-NEXT: [[LB:%.*]] = and i32 [[X:%.*]], 8 565; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[LB]], 0 566; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) 567; CHECK-NEXT: ret i32 0 568; 569 %lb = and i32 %x, 8 570 %cmp = icmp ne i32 %lb, 0 571 call void @llvm.assume(i1 %cmp) 572 %x2 = sub i32 0, %x 573 %x3 = and i32 %x2, %x 574 %z = and i32 %x3, 32 575 ret i32 %z 576} 577 578define <2 x i1> @blsmsk_ne_no_proof_vec(<2 x i32> %x) { 579; CHECK-LABEL: @blsmsk_ne_no_proof_vec( 580; CHECK-NEXT: [[X1:%.*]] = or <2 x i32> [[X:%.*]], splat (i32 10) 581; CHECK-NEXT: [[X2:%.*]] = add nsw <2 x i32> [[X1]], <i32 -2, i32 -3> 582; CHECK-NEXT: [[X3:%.*]] = xor <2 x i32> [[X2]], [[X1]] 583; CHECK-NEXT: [[Z:%.*]] = icmp ne <2 x i32> [[X3]], splat (i32 8) 584; CHECK-NEXT: ret <2 x i1> [[Z]] 585; 586 %x1 = or <2 x i32> %x, <i32 10, i32 10> 587 %x2 = sub <2 x i32> %x1, <i32 2, i32 3> 588 %x3 = xor <2 x i32> %x2, %x1 589 %z = icmp ne <2 x i32> %x3, <i32 8, i32 8> 590 ret <2 x i1> %z 591} 592 593define <2 x i32> @blsmsk_add_noeval_vec(<2 x i32> %x) { 594; CHECK-LABEL: @blsmsk_add_noeval_vec( 595; CHECK-NEXT: [[X1:%.*]] = or <2 x i32> [[X:%.*]], splat (i32 9) 596; CHECK-NEXT: [[X2:%.*]] = add <2 x i32> [[X1]], <i32 1, i32 -2> 597; CHECK-NEXT: [[X3:%.*]] = xor <2 x i32> [[X2]], [[X1]] 598; CHECK-NEXT: [[Z:%.*]] = add <2 x i32> [[X3]], splat (i32 32) 599; CHECK-NEXT: ret <2 x i32> [[Z]] 600; 601 %x1 = or <2 x i32> %x, <i32 9, i32 9> 602 %x2 = add <2 x i32> %x1, <i32 1, i32 -2> 603 %x3 = xor <2 x i32> %x2, %x1 604 %z = add <2 x i32> %x3, <i32 32, i32 32> 605 ret <2 x i32> %z 606} 607 608define i1 @blsmsk_eq_no_proof(i32 %x) { 609; CHECK-LABEL: @blsmsk_eq_no_proof( 610; CHECK-NEXT: ret i1 false 611; 612 %x1 = or i32 %x, 10 613 %x2 = add i32 %x1, -2 614 %x3 = xor i32 %x2, %x1 615 %z = icmp eq i32 %x3, 8 616 ret i1 %z 617} 618 619 620define i32 @blsmsk_add_no_eval(i32 %x) { 621; CHECK-LABEL: @blsmsk_add_no_eval( 622; CHECK-NEXT: [[X1:%.*]] = or i32 [[X:%.*]], 9 623; CHECK-NEXT: [[X2:%.*]] = add nsw i32 [[X1]], -3 624; CHECK-NEXT: [[X3:%.*]] = xor i32 [[X1]], [[X2]] 625; CHECK-NEXT: [[Z:%.*]] = add i32 [[X3]], 32 626; CHECK-NEXT: ret i32 [[Z]] 627; 628 %x1 = or i32 %x, 9 629 %x2 = sub i32 %x1, 3 630 %x3 = xor i32 %x1, %x2 631 %z = add i32 %x3, 32 632 ret i32 %z 633} 634 635define i32 @blsmsk_add_no_eval2(i32 %x) { 636; CHECK-LABEL: @blsmsk_add_no_eval2( 637; CHECK-NEXT: [[X1:%.*]] = or i32 [[X:%.*]], 256 638; CHECK-NEXT: [[X2:%.*]] = add nsw i32 [[X1]], -1 639; CHECK-NEXT: [[X3:%.*]] = xor i32 [[X1]], [[X2]] 640; CHECK-NEXT: [[Z:%.*]] = add nuw nsw i32 [[X3]], 32 641; CHECK-NEXT: ret i32 [[Z]] 642; 643 %x1 = or i32 %x, 256 644 %x2 = sub i32 %x1, 1 645 %x3 = xor i32 %x1, %x2 646 %z = add i32 %x3, 32 647 ret i32 %z 648} 649 650define <2 x i32> @blsmsk_xor_no_eval_vec(<2 x i32> %x) { 651; CHECK-LABEL: @blsmsk_xor_no_eval_vec( 652; CHECK-NEXT: [[X1:%.*]] = or <2 x i32> [[X:%.*]], splat (i32 34) 653; CHECK-NEXT: [[X2:%.*]] = add <2 x i32> [[X1]], <i32 -9, i32 1> 654; CHECK-NEXT: [[X3:%.*]] = xor <2 x i32> [[X2]], [[X1]] 655; CHECK-NEXT: [[Z:%.*]] = xor <2 x i32> [[X3]], splat (i32 32) 656; CHECK-NEXT: ret <2 x i32> [[Z]] 657; 658 %x1 = or <2 x i32> %x, <i32 34, i32 34> 659 %x2 = add <2 x i32> %x1, <i32 -9, i32 1> 660 %x3 = xor <2 x i32> %x2, %x1 661 %z = xor <2 x i32> %x3, <i32 32, i32 32> 662 ret <2 x i32> %z 663} 664 665define i32 @blsmsk_xor_no_eval_assume(i32 %x) { 666; CHECK-LABEL: @blsmsk_xor_no_eval_assume( 667; CHECK-NEXT: [[LB:%.*]] = and i32 [[X:%.*]], 1 668; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[LB]], 0 669; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) 670; CHECK-NEXT: [[X2:%.*]] = add i32 [[X]], -1 671; CHECK-NEXT: [[X3:%.*]] = xor i32 [[X]], [[X2]] 672; CHECK-NEXT: [[Z:%.*]] = xor i32 [[X3]], 32 673; CHECK-NEXT: ret i32 [[Z]] 674; 675 %lb = and i32 %x, 1 676 %cmp = icmp ne i32 %lb, 1 677 call void @llvm.assume(i1 %cmp) 678 %x2 = sub i32 %x, 1 679 %x3 = xor i32 %x, %x2 680 %z = xor i32 %x3, 32 681 ret i32 %z 682} 683 684define i32 @blsmsk_xor_no_eval_assume2(i32 %x) { 685; CHECK-LABEL: @blsmsk_xor_no_eval_assume2( 686; CHECK-NEXT: [[LB:%.*]] = and i32 [[X:%.*]], 128 687; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[LB]], 0 688; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) 689; CHECK-NEXT: [[X2:%.*]] = add nsw i32 [[X]], -1 690; CHECK-NEXT: [[X3:%.*]] = xor i32 [[X]], [[X2]] 691; CHECK-NEXT: [[Z:%.*]] = xor i32 [[X3]], 32 692; CHECK-NEXT: ret i32 [[Z]] 693; 694 %lb = and i32 %x, 128 695 %cmp = icmp ne i32 %lb, 0 696 call void @llvm.assume(i1 %cmp) 697 %x2 = sub i32 %x, 1 698 %x3 = xor i32 %x, %x2 699 %z = xor i32 %x3, 32 700 ret i32 %z 701} 702 703define i1 @blsi_ne_no_proof2(i32 %x) { 704; CHECK-LABEL: @blsi_ne_no_proof2( 705; CHECK-NEXT: [[X1:%.*]] = or i32 [[X:%.*]], 512 706; CHECK-NEXT: [[X2:%.*]] = sub nsw i32 0, [[X1]] 707; CHECK-NEXT: [[X3:%.*]] = and i32 [[X1]], [[X2]] 708; CHECK-NEXT: [[Z:%.*]] = icmp ne i32 [[X3]], 8 709; CHECK-NEXT: ret i1 [[Z]] 710; 711 %x1 = or i32 %x, 512 712 %x2 = sub i32 0, %x1 713 %x3 = and i32 %x2, %x1 714 %z = icmp ne i32 %x3, 8 715 ret i1 %z 716} 717 718 719define i32 @blsi_or_no_eval(i32 %x) { 720; CHECK-LABEL: @blsi_or_no_eval( 721; CHECK-NEXT: [[X1:%.*]] = or i32 [[X:%.*]], 129 722; CHECK-NEXT: [[X2:%.*]] = sub nsw i32 2, [[X1]] 723; CHECK-NEXT: [[X3:%.*]] = and i32 [[X2]], [[X1]] 724; CHECK-NEXT: [[Z:%.*]] = or i32 [[X3]], 32 725; CHECK-NEXT: ret i32 [[Z]] 726; 727 %x1 = or i32 %x, 129 728 %x2 = sub i32 2, %x1 729 %x3 = and i32 %x2, %x1 730 %z = or i32 %x3, 32 731 ret i32 %z 732} 733 734define <2 x i32> @blsi_or_no_partial_eval_vec(<2 x i32> %x) { 735; CHECK-LABEL: @blsi_or_no_partial_eval_vec( 736; CHECK-NEXT: [[X1:%.*]] = or <2 x i32> [[X:%.*]], splat (i32 30) 737; CHECK-NEXT: [[X2:%.*]] = sub nsw <2 x i32> <i32 0, i32 1>, [[X1]] 738; CHECK-NEXT: [[X3:%.*]] = and <2 x i32> [[X1]], [[X2]] 739; CHECK-NEXT: [[Z:%.*]] = or <2 x i32> [[X3]], splat (i32 32) 740; CHECK-NEXT: ret <2 x i32> [[Z]] 741; 742 %x1 = or <2 x i32> %x, <i32 30, i32 30> 743 %x2 = sub <2 x i32> <i32 0, i32 1>, %x1 744 %x3 = and <2 x i32> %x1, %x2 745 %z = or <2 x i32> %x3, <i32 32, i32 32> 746 ret <2 x i32> %z 747} 748 749 750;; Test that if we have different knowledge about lowbit of X/-X that we select the minimum. 751define i1 @blsi_differing_lowbits(i8 %x) { 752; CHECK-LABEL: @blsi_differing_lowbits( 753; CHECK-NEXT: [[Z:%.*]] = sub i8 0, [[X:%.*]] 754; CHECK-NEXT: [[LB:%.*]] = and i8 [[Z]], 2 755; CHECK-NEXT: [[NE:%.*]] = icmp ne i8 [[LB]], 0 756; CHECK-NEXT: call void @llvm.assume(i1 [[NE]]) 757; CHECK-NEXT: ret i1 false 758; 759 %y = or i8 %x, 8 760 %z = sub i8 0, %y 761 %lb = and i8 %z, 2 762 %ne = icmp ne i8 %lb, 0 763 call void @llvm.assume(i1 %ne) 764 %o = and i8 %z, %y 765 %r = icmp eq i8 %o, 4 766 ret i1 %r 767} 768 769define i1 @blsi_differing_lowbits2(i8 %x) { 770; CHECK-LABEL: @blsi_differing_lowbits2( 771; CHECK-NEXT: [[Z:%.*]] = sub nsw i8 0, [[X:%.*]] 772; CHECK-NEXT: [[LB:%.*]] = and i8 [[Z]], 8 773; CHECK-NEXT: [[NE:%.*]] = icmp ne i8 [[LB]], 0 774; CHECK-NEXT: call void @llvm.assume(i1 [[NE]]) 775; CHECK-NEXT: [[LB2:%.*]] = and i8 [[X]], 2 776; CHECK-NEXT: [[NE2:%.*]] = icmp ne i8 [[LB2]], 0 777; CHECK-NEXT: call void @llvm.assume(i1 [[NE2]]) 778; CHECK-NEXT: ret i1 false 779; 780 %z = sub i8 0, %x 781 %lb = and i8 %z, 8 782 %ne = icmp ne i8 %lb, 0 783 call void @llvm.assume(i1 %ne) 784 %lb2 = and i8 %x, 2 785 %ne2 = icmp ne i8 %lb2, 0 786 call void @llvm.assume(i1 %ne2) 787 %o = and i8 %z, %x 788 %r = icmp eq i8 %o, 4 789 ret i1 %r 790} 791