1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -instsimplify -S | FileCheck %s 3 4declare i32 @llvm.smax.i32(i32, i32) 5declare <2 x i32> @llvm.umin.v2i32(<2 x i32>, <2 x i32>) 6 7define i8 @and0(i8 %x) { 8; CHECK-LABEL: @and0( 9; CHECK-NEXT: ret i8 0 10; 11 %r = and i8 %x, 0 12 ret i8 %r 13} 14 15define <2 x i8> @and0_vec_undef_elt(<2 x i8> %x) { 16; CHECK-LABEL: @and0_vec_undef_elt( 17; CHECK-NEXT: ret <2 x i8> zeroinitializer 18; 19 %r = and <2 x i8> %x, <i8 undef, i8 0> 20 ret <2 x i8> %r 21} 22 23; add nsw (xor X, signbit), signbit --> X 24 25define <2 x i32> @add_nsw_signbit(<2 x i32> %x) { 26; CHECK-LABEL: @add_nsw_signbit( 27; CHECK-NEXT: ret <2 x i32> [[X:%.*]] 28; 29 %y = xor <2 x i32> %x, <i32 -2147483648, i32 -2147483648> 30 %z = add nsw <2 x i32> %y, <i32 -2147483648, i32 -2147483648> 31 ret <2 x i32> %z 32} 33 34; Undef elements in either constant vector are ok. 35 36define <2 x i32> @add_nsw_signbit_undef(<2 x i32> %x) { 37; CHECK-LABEL: @add_nsw_signbit_undef( 38; CHECK-NEXT: ret <2 x i32> [[X:%.*]] 39; 40 %y = xor <2 x i32> %x, <i32 undef, i32 -2147483648> 41 %z = add nsw <2 x i32> %y, <i32 -2147483648, i32 undef> 42 ret <2 x i32> %z 43} 44 45; add nuw (xor X, signbit), signbit --> X 46 47define <2 x i5> @add_nuw_signbit(<2 x i5> %x) { 48; CHECK-LABEL: @add_nuw_signbit( 49; CHECK-NEXT: ret <2 x i5> [[X:%.*]] 50; 51 %y = xor <2 x i5> %x, <i5 -16, i5 -16> 52 %z = add nuw <2 x i5> %y, <i5 -16, i5 -16> 53 ret <2 x i5> %z 54} 55 56; Undef elements in either constant vector are ok. 57 58define <2 x i5> @add_nuw_signbit_undef(<2 x i5> %x) { 59; CHECK-LABEL: @add_nuw_signbit_undef( 60; CHECK-NEXT: ret <2 x i5> [[X:%.*]] 61; 62 %y = xor <2 x i5> %x, <i5 -16, i5 undef> 63 %z = add nuw <2 x i5> %y, <i5 undef, i5 -16> 64 ret <2 x i5> %z 65} 66 67define i64 @pow2(i32 %x) { 68; CHECK-LABEL: @pow2( 69; CHECK-NEXT: [[NEGX:%.*]] = sub i32 0, [[X:%.*]] 70; CHECK-NEXT: [[X2:%.*]] = and i32 [[X]], [[NEGX]] 71; CHECK-NEXT: [[E:%.*]] = zext i32 [[X2]] to i64 72; CHECK-NEXT: ret i64 [[E]] 73; 74 %negx = sub i32 0, %x 75 %x2 = and i32 %x, %negx 76 %e = zext i32 %x2 to i64 77 %nege = sub i64 0, %e 78 %e2 = and i64 %e, %nege 79 ret i64 %e2 80} 81 82define i64 @pow2b(i32 %x) { 83; CHECK-LABEL: @pow2b( 84; CHECK-NEXT: [[SH:%.*]] = shl i32 2, [[X:%.*]] 85; CHECK-NEXT: [[E:%.*]] = zext i32 [[SH]] to i64 86; CHECK-NEXT: ret i64 [[E]] 87; 88 %sh = shl i32 2, %x 89 %e = zext i32 %sh to i64 90 %nege = sub i64 0, %e 91 %e2 = and i64 %e, %nege 92 ret i64 %e2 93} 94 95define i32 @pow2b_max(i32 %x, i32 %y) { 96; CHECK-LABEL: @pow2b_max( 97; CHECK-NEXT: [[SHX:%.*]] = shl i32 2, [[X:%.*]] 98; CHECK-NEXT: [[SHY:%.*]] = shl i32 32, [[Y:%.*]] 99; CHECK-NEXT: [[M:%.*]] = call i32 @llvm.smax.i32(i32 [[SHX]], i32 [[SHY]]) 100; CHECK-NEXT: ret i32 [[M]] 101; 102 %shx = shl i32 2, %x 103 %shy = shl i32 32, %y 104 %m = call i32 @llvm.smax.i32(i32 %shx, i32 %shy) 105 %neg = sub i32 0, %m 106 %r = and i32 %m, %neg 107 ret i32 %r 108} 109 110; Power-of-2-or-zero value has no bits in common with its decrement. 111 112define i32 @pow2_decrement(i32 %p) { 113; CHECK-LABEL: @pow2_decrement( 114; CHECK-NEXT: ret i32 0 115; 116 %x = shl i32 1, %p 117 %a = add i32 %x, -1 118 %r = and i32 %a, %x 119 ret i32 %r 120} 121 122define <2 x i32> @pow2_decrement_commute_vec(<2 x i32> %p) { 123; CHECK-LABEL: @pow2_decrement_commute_vec( 124; CHECK-NEXT: ret <2 x i32> zeroinitializer 125; 126 %x = and <2 x i32> %p, <i32 2048, i32 2048> 127 %a = add <2 x i32> %x, <i32 -1, i32 -1> 128 %r = and <2 x i32> %x, %a 129 ret <2 x i32> %r 130} 131 132define <2 x i32> @pow2_decrement_min_vec(<2 x i32> %x, <2 x i32> %y) { 133; CHECK-LABEL: @pow2_decrement_min_vec( 134; CHECK-NEXT: ret <2 x i32> zeroinitializer 135; 136 %p1 = and <2 x i32> %x, <i32 2048, i32 2048> 137 %p2 = shl <2 x i32> <i32 1, i32 1>, %y 138 %m = call <2 x i32> @llvm.umin.v2i32(<2 x i32> %p1, <2 x i32> %p2) 139 %a = add <2 x i32> %m, <i32 -1, i32 -1> 140 %r = and <2 x i32> %m, %a 141 ret <2 x i32> %r 142} 143 144define i1 @and_of_icmps0(i32 %b) { 145; CHECK-LABEL: @and_of_icmps0( 146; CHECK-NEXT: ret i1 false 147; 148 %1 = add i32 %b, 2 149 %2 = icmp ult i32 %1, 4 150 %cmp3 = icmp sgt i32 %b, 2 151 %cmp = and i1 %2, %cmp3 152 ret i1 %cmp 153} 154 155define <2 x i1> @and_of_icmps0_vec(<2 x i32> %b) { 156; CHECK-LABEL: @and_of_icmps0_vec( 157; CHECK-NEXT: ret <2 x i1> zeroinitializer 158; 159 %1 = add <2 x i32> %b, <i32 2, i32 2> 160 %2 = icmp ult <2 x i32> %1, <i32 4, i32 4> 161 %cmp3 = icmp sgt <2 x i32> %b, <i32 2, i32 2> 162 %cmp = and <2 x i1> %2, %cmp3 163 ret <2 x i1> %cmp 164} 165 166define i1 @and_of_icmps1(i32 %b) { 167; CHECK-LABEL: @and_of_icmps1( 168; CHECK-NEXT: ret i1 false 169; 170 %1 = add nsw i32 %b, 2 171 %2 = icmp slt i32 %1, 4 172 %cmp3 = icmp sgt i32 %b, 2 173 %cmp = and i1 %2, %cmp3 174 ret i1 %cmp 175} 176 177define <2 x i1> @and_of_icmps1_vec(<2 x i32> %b) { 178; CHECK-LABEL: @and_of_icmps1_vec( 179; CHECK-NEXT: ret <2 x i1> zeroinitializer 180; 181 %1 = add nsw <2 x i32> %b, <i32 2, i32 2> 182 %2 = icmp slt <2 x i32> %1, <i32 4, i32 4> 183 %cmp3 = icmp sgt <2 x i32> %b, <i32 2, i32 2> 184 %cmp = and <2 x i1> %2, %cmp3 185 ret <2 x i1> %cmp 186} 187 188define i1 @and_of_icmps2(i32 %b) { 189; CHECK-LABEL: @and_of_icmps2( 190; CHECK-NEXT: ret i1 false 191; 192 %1 = add i32 %b, 2 193 %2 = icmp ule i32 %1, 3 194 %cmp3 = icmp sgt i32 %b, 2 195 %cmp = and i1 %2, %cmp3 196 ret i1 %cmp 197} 198 199define <2 x i1> @and_of_icmps2_vec(<2 x i32> %b) { 200; CHECK-LABEL: @and_of_icmps2_vec( 201; CHECK-NEXT: ret <2 x i1> zeroinitializer 202; 203 %1 = add <2 x i32> %b, <i32 2, i32 2> 204 %2 = icmp ule <2 x i32> %1, <i32 3, i32 3> 205 %cmp3 = icmp sgt <2 x i32> %b, <i32 2, i32 2> 206 %cmp = and <2 x i1> %2, %cmp3 207 ret <2 x i1> %cmp 208} 209 210define i1 @and_of_icmps3(i32 %b) { 211; CHECK-LABEL: @and_of_icmps3( 212; CHECK-NEXT: ret i1 false 213; 214 %1 = add nsw i32 %b, 2 215 %2 = icmp sle i32 %1, 3 216 %cmp3 = icmp sgt i32 %b, 2 217 %cmp = and i1 %2, %cmp3 218 ret i1 %cmp 219} 220 221define <2 x i1> @and_of_icmps3_vec(<2 x i32> %b) { 222; CHECK-LABEL: @and_of_icmps3_vec( 223; CHECK-NEXT: ret <2 x i1> zeroinitializer 224; 225 %1 = add nsw <2 x i32> %b, <i32 2, i32 2> 226 %2 = icmp sle <2 x i32> %1, <i32 3, i32 3> 227 %cmp3 = icmp sgt <2 x i32> %b, <i32 2, i32 2> 228 %cmp = and <2 x i1> %2, %cmp3 229 ret <2 x i1> %cmp 230} 231 232define i1 @and_of_icmps4(i32 %b) { 233; CHECK-LABEL: @and_of_icmps4( 234; CHECK-NEXT: ret i1 false 235; 236 %1 = add nuw i32 %b, 2 237 %2 = icmp ult i32 %1, 4 238 %cmp3 = icmp ugt i32 %b, 2 239 %cmp = and i1 %2, %cmp3 240 ret i1 %cmp 241} 242 243define <2 x i1> @and_of_icmps4_vec(<2 x i32> %b) { 244; CHECK-LABEL: @and_of_icmps4_vec( 245; CHECK-NEXT: ret <2 x i1> zeroinitializer 246; 247 %1 = add nuw <2 x i32> %b, <i32 2, i32 2> 248 %2 = icmp ult <2 x i32> %1, <i32 4, i32 4> 249 %cmp3 = icmp ugt <2 x i32> %b, <i32 2, i32 2> 250 %cmp = and <2 x i1> %2, %cmp3 251 ret <2 x i1> %cmp 252} 253 254define i1 @and_of_icmps5(i32 %b) { 255; CHECK-LABEL: @and_of_icmps5( 256; CHECK-NEXT: ret i1 false 257; 258 %1 = add nuw i32 %b, 2 259 %2 = icmp ule i32 %1, 3 260 %cmp3 = icmp ugt i32 %b, 2 261 %cmp = and i1 %2, %cmp3 262 ret i1 %cmp 263} 264 265define <2 x i1> @and_of_icmps5_vec(<2 x i32> %b) { 266; CHECK-LABEL: @and_of_icmps5_vec( 267; CHECK-NEXT: ret <2 x i1> zeroinitializer 268; 269 %1 = add nuw <2 x i32> %b, <i32 2, i32 2> 270 %2 = icmp ule <2 x i32> %1, <i32 3, i32 3> 271 %cmp3 = icmp ugt <2 x i32> %b, <i32 2, i32 2> 272 %cmp = and <2 x i1> %2, %cmp3 273 ret <2 x i1> %cmp 274} 275 276define i1 @or_of_icmps0(i32 %b) { 277; CHECK-LABEL: @or_of_icmps0( 278; CHECK-NEXT: ret i1 true 279; 280 %1 = add i32 %b, 2 281 %2 = icmp uge i32 %1, 4 282 %cmp3 = icmp sle i32 %b, 2 283 %cmp = or i1 %2, %cmp3 284 ret i1 %cmp 285} 286 287define <2 x i1> @or_of_icmps0_vec(<2 x i32> %b) { 288; CHECK-LABEL: @or_of_icmps0_vec( 289; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 290; 291 %1 = add <2 x i32> %b, <i32 2, i32 2> 292 %2 = icmp uge <2 x i32> %1, <i32 4, i32 4> 293 %cmp3 = icmp sle <2 x i32> %b, <i32 2, i32 2> 294 %cmp = or <2 x i1> %2, %cmp3 295 ret <2 x i1> %cmp 296} 297 298define i1 @or_of_icmps1(i32 %b) { 299; CHECK-LABEL: @or_of_icmps1( 300; CHECK-NEXT: ret i1 true 301; 302 %1 = add nsw i32 %b, 2 303 %2 = icmp sge i32 %1, 4 304 %cmp3 = icmp sle i32 %b, 2 305 %cmp = or i1 %2, %cmp3 306 ret i1 %cmp 307} 308 309define <2 x i1> @or_of_icmps1_vec(<2 x i32> %b) { 310; CHECK-LABEL: @or_of_icmps1_vec( 311; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 312; 313 %1 = add nsw <2 x i32> %b, <i32 2, i32 2> 314 %2 = icmp sge <2 x i32> %1, <i32 4, i32 4> 315 %cmp3 = icmp sle <2 x i32> %b, <i32 2, i32 2> 316 %cmp = or <2 x i1> %2, %cmp3 317 ret <2 x i1> %cmp 318} 319 320define i1 @or_of_icmps2(i32 %b) { 321; CHECK-LABEL: @or_of_icmps2( 322; CHECK-NEXT: ret i1 true 323; 324 %1 = add i32 %b, 2 325 %2 = icmp ugt i32 %1, 3 326 %cmp3 = icmp sle i32 %b, 2 327 %cmp = or i1 %2, %cmp3 328 ret i1 %cmp 329} 330 331define <2 x i1> @or_of_icmps2_vec(<2 x i32> %b) { 332; CHECK-LABEL: @or_of_icmps2_vec( 333; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 334; 335 %1 = add <2 x i32> %b, <i32 2, i32 2> 336 %2 = icmp ugt <2 x i32> %1, <i32 3, i32 3> 337 %cmp3 = icmp sle <2 x i32> %b, <i32 2, i32 2> 338 %cmp = or <2 x i1> %2, %cmp3 339 ret <2 x i1> %cmp 340} 341 342define i1 @or_of_icmps3(i32 %b) { 343; CHECK-LABEL: @or_of_icmps3( 344; CHECK-NEXT: ret i1 true 345; 346 %1 = add nsw i32 %b, 2 347 %2 = icmp sgt i32 %1, 3 348 %cmp3 = icmp sle i32 %b, 2 349 %cmp = or i1 %2, %cmp3 350 ret i1 %cmp 351} 352 353define <2 x i1> @or_of_icmps3_vec(<2 x i32> %b) { 354; CHECK-LABEL: @or_of_icmps3_vec( 355; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 356; 357 %1 = add nsw <2 x i32> %b, <i32 2, i32 2> 358 %2 = icmp sgt <2 x i32> %1, <i32 3, i32 3> 359 %cmp3 = icmp sle <2 x i32> %b, <i32 2, i32 2> 360 %cmp = or <2 x i1> %2, %cmp3 361 ret <2 x i1> %cmp 362} 363 364define i1 @or_of_icmps4(i32 %b) { 365; CHECK-LABEL: @or_of_icmps4( 366; CHECK-NEXT: ret i1 true 367; 368 %1 = add nuw i32 %b, 2 369 %2 = icmp uge i32 %1, 4 370 %cmp3 = icmp ule i32 %b, 2 371 %cmp = or i1 %2, %cmp3 372 ret i1 %cmp 373} 374 375define <2 x i1> @or_of_icmps4_vec(<2 x i32> %b) { 376; CHECK-LABEL: @or_of_icmps4_vec( 377; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 378; 379 %1 = add nuw <2 x i32> %b, <i32 2, i32 2> 380 %2 = icmp uge <2 x i32> %1, <i32 4, i32 4> 381 %cmp3 = icmp ule <2 x i32> %b, <i32 2, i32 2> 382 %cmp = or <2 x i1> %2, %cmp3 383 ret <2 x i1> %cmp 384} 385 386define i1 @or_of_icmps5(i32 %b) { 387; CHECK-LABEL: @or_of_icmps5( 388; CHECK-NEXT: ret i1 true 389; 390 %1 = add nuw i32 %b, 2 391 %2 = icmp ugt i32 %1, 3 392 %cmp3 = icmp ule i32 %b, 2 393 %cmp = or i1 %2, %cmp3 394 ret i1 %cmp 395} 396 397define <2 x i1> @or_of_icmps5_vec(<2 x i32> %b) { 398; CHECK-LABEL: @or_of_icmps5_vec( 399; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 400; 401 %1 = add nuw <2 x i32> %b, <i32 2, i32 2> 402 %2 = icmp ugt <2 x i32> %1, <i32 3, i32 3> 403 %cmp3 = icmp ule <2 x i32> %b, <i32 2, i32 2> 404 %cmp = or <2 x i1> %2, %cmp3 405 ret <2 x i1> %cmp 406} 407 408define i32 @neg_nuw(i32 %x) { 409; CHECK-LABEL: @neg_nuw( 410; CHECK-NEXT: ret i32 0 411; 412 %neg = sub nuw i32 0, %x 413 ret i32 %neg 414} 415 416; PR27869 - Look through casts to eliminate cmps and bitwise logic. 417 418define i32 @and_of_zexted_icmps(i32 %i) { 419; CHECK-LABEL: @and_of_zexted_icmps( 420; CHECK-NEXT: ret i32 0 421; 422 %cmp0 = icmp eq i32 %i, 0 423 %conv0 = zext i1 %cmp0 to i32 424 %cmp1 = icmp ugt i32 %i, 4 425 %conv1 = zext i1 %cmp1 to i32 426 %and = and i32 %conv0, %conv1 427 ret i32 %and 428} 429 430; Make sure vectors work too. 431 432define <4 x i32> @and_of_zexted_icmps_vec(<4 x i32> %i) { 433; CHECK-LABEL: @and_of_zexted_icmps_vec( 434; CHECK-NEXT: ret <4 x i32> zeroinitializer 435; 436 %cmp0 = icmp eq <4 x i32> %i, zeroinitializer 437 %conv0 = zext <4 x i1> %cmp0 to <4 x i32> 438 %cmp1 = icmp slt <4 x i32> %i, zeroinitializer 439 %conv1 = zext <4 x i1> %cmp1 to <4 x i32> 440 %and = and <4 x i32> %conv0, %conv1 441 ret <4 x i32> %and 442} 443 444; Try a different cast and weird types. 445 446define i5 @and_of_sexted_icmps(i3 %i) { 447; CHECK-LABEL: @and_of_sexted_icmps( 448; CHECK-NEXT: ret i5 0 449; 450 %cmp0 = icmp eq i3 %i, 0 451 %conv0 = sext i1 %cmp0 to i5 452 %cmp1 = icmp ugt i3 %i, 1 453 %conv1 = sext i1 %cmp1 to i5 454 %and = and i5 %conv0, %conv1 455 ret i5 %and 456} 457 458; Try a different cast and weird vector types. 459 460define i3 @and_of_bitcast_icmps_vec(<3 x i65> %i) { 461; CHECK-LABEL: @and_of_bitcast_icmps_vec( 462; CHECK-NEXT: ret i3 0 463; 464 %cmp0 = icmp sgt <3 x i65> %i, zeroinitializer 465 %conv0 = bitcast <3 x i1> %cmp0 to i3 466 %cmp1 = icmp slt <3 x i65> %i, zeroinitializer 467 %conv1 = bitcast <3 x i1> %cmp1 to i3 468 %and = and i3 %conv0, %conv1 469 ret i3 %and 470} 471 472; We can't do this if the casts are different. 473 474define i16 @and_of_different_cast_icmps(i8 %i) { 475; CHECK-LABEL: @and_of_different_cast_icmps( 476; CHECK-NEXT: [[CMP0:%.*]] = icmp eq i8 [[I:%.*]], 0 477; CHECK-NEXT: [[CONV0:%.*]] = zext i1 [[CMP0]] to i16 478; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[I]], 1 479; CHECK-NEXT: [[CONV1:%.*]] = sext i1 [[CMP1]] to i16 480; CHECK-NEXT: [[AND:%.*]] = and i16 [[CONV0]], [[CONV1]] 481; CHECK-NEXT: ret i16 [[AND]] 482; 483 %cmp0 = icmp eq i8 %i, 0 484 %conv0 = zext i1 %cmp0 to i16 485 %cmp1 = icmp eq i8 %i, 1 486 %conv1 = sext i1 %cmp1 to i16 487 %and = and i16 %conv0, %conv1 488 ret i16 %and 489} 490 491define <2 x i3> @and_of_different_cast_icmps_vec(<2 x i8> %i, <2 x i16> %j) { 492; CHECK-LABEL: @and_of_different_cast_icmps_vec( 493; CHECK-NEXT: [[CMP0:%.*]] = icmp eq <2 x i8> [[I:%.*]], zeroinitializer 494; CHECK-NEXT: [[CONV0:%.*]] = zext <2 x i1> [[CMP0]] to <2 x i3> 495; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt <2 x i16> [[J:%.*]], <i16 1, i16 1> 496; CHECK-NEXT: [[CONV1:%.*]] = zext <2 x i1> [[CMP1]] to <2 x i3> 497; CHECK-NEXT: [[AND:%.*]] = and <2 x i3> [[CONV0]], [[CONV1]] 498; CHECK-NEXT: ret <2 x i3> [[AND]] 499; 500 %cmp0 = icmp eq <2 x i8> %i, zeroinitializer 501 %conv0 = zext <2 x i1> %cmp0 to <2 x i3> 502 %cmp1 = icmp ugt <2 x i16> %j, <i16 1, i16 1> 503 %conv1 = zext <2 x i1> %cmp1 to <2 x i3> 504 %and = and <2 x i3> %conv0, %conv1 505 ret <2 x i3> %and 506} 507 508; limit 509 510define i32 @or_of_zexted_icmps(i32 %i) { 511; CHECK-LABEL: @or_of_zexted_icmps( 512; CHECK-NEXT: ret i32 1 513; 514 %cmp0 = icmp ne i32 %i, 0 515 %conv0 = zext i1 %cmp0 to i32 516 %cmp1 = icmp uge i32 4, %i 517 %conv1 = zext i1 %cmp1 to i32 518 %or = or i32 %conv0, %conv1 519 ret i32 %or 520} 521 522; Try a different cast and weird vector types. 523 524define i3 @or_of_bitcast_icmps_vec(<3 x i65> %i) { 525; CHECK-LABEL: @or_of_bitcast_icmps_vec( 526; CHECK-NEXT: ret i3 bitcast (<3 x i1> <i1 true, i1 true, i1 true> to i3) 527; 528 %cmp0 = icmp sge <3 x i65> %i, zeroinitializer 529 %conv0 = bitcast <3 x i1> %cmp0 to i3 530 %cmp1 = icmp slt <3 x i65> %i, zeroinitializer 531 %conv1 = bitcast <3 x i1> %cmp1 to i3 532 %or = or i3 %conv0, %conv1 533 ret i3 %or 534} 535 536; We can't simplify if the casts are different. 537 538define i16 @or_of_different_cast_icmps(i8 %i) { 539; CHECK-LABEL: @or_of_different_cast_icmps( 540; CHECK-NEXT: [[CMP0:%.*]] = icmp ne i8 [[I:%.*]], 0 541; CHECK-NEXT: [[CONV0:%.*]] = zext i1 [[CMP0]] to i16 542; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i8 [[I]], 1 543; CHECK-NEXT: [[CONV1:%.*]] = sext i1 [[CMP1]] to i16 544; CHECK-NEXT: [[OR:%.*]] = or i16 [[CONV0]], [[CONV1]] 545; CHECK-NEXT: ret i16 [[OR]] 546; 547 %cmp0 = icmp ne i8 %i, 0 548 %conv0 = zext i1 %cmp0 to i16 549 %cmp1 = icmp ne i8 %i, 1 550 %conv1 = sext i1 %cmp1 to i16 551 %or = or i16 %conv0, %conv1 552 ret i16 %or 553} 554 555; (A & ~B) | (A ^ B) -> A ^ B 556 557define i32 @test43(i32 %a, i32 %b) { 558; CHECK-LABEL: @test43( 559; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], [[B:%.*]] 560; CHECK-NEXT: ret i32 [[XOR]] 561; 562 %neg = xor i32 %b, -1 563 %and = and i32 %a, %neg 564 %xor = xor i32 %a, %b 565 %or = or i32 %and, %xor 566 ret i32 %or 567} 568 569define i32 @test43_commuted_and(i32 %a, i32 %b) { 570; CHECK-LABEL: @test43_commuted_and( 571; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], [[B:%.*]] 572; CHECK-NEXT: ret i32 [[XOR]] 573; 574 %neg = xor i32 %b, -1 575 %and = and i32 %neg, %a 576 %xor = xor i32 %a, %b 577 %or = or i32 %and, %xor 578 ret i32 %or 579} 580 581; Commute operands of the 'or'. 582; (A ^ B) | (A & ~B) -> A ^ B 583 584define i32 @test44(i32 %a, i32 %b) { 585; CHECK-LABEL: @test44( 586; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], [[B:%.*]] 587; CHECK-NEXT: ret i32 [[XOR]] 588; 589 %xor = xor i32 %a, %b 590 %neg = xor i32 %b, -1 591 %and = and i32 %a, %neg 592 %or = or i32 %xor, %and 593 ret i32 %or 594} 595 596define i32 @test44_commuted_and(i32 %a, i32 %b) { 597; CHECK-LABEL: @test44_commuted_and( 598; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], [[B:%.*]] 599; CHECK-NEXT: ret i32 [[XOR]] 600; 601 %xor = xor i32 %a, %b 602 %neg = xor i32 %b, -1 603 %and = and i32 %neg, %a 604 %or = or i32 %xor, %and 605 ret i32 %or 606} 607 608; (~A & ~B) | (~A ^ B) -> ~A ^ B 609 610define i32 @test45(i32 %a, i32 %b) { 611; CHECK-LABEL: @test45( 612; CHECK-NEXT: [[NEGB:%.*]] = xor i32 [[B:%.*]], -1 613; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], [[NEGB]] 614; CHECK-NEXT: ret i32 [[XOR]] 615; 616 %nega = xor i32 %a, -1 617 %negb = xor i32 %b, -1 618 %and = and i32 %nega, %negb 619 %xor = xor i32 %a, %negb 620 %or = or i32 %and, %xor 621 ret i32 %or 622} 623 624define i32 @test45_commuted_and(i32 %a, i32 %b) { 625; CHECK-LABEL: @test45_commuted_and( 626; CHECK-NEXT: [[NEGB:%.*]] = xor i32 [[B:%.*]], -1 627; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], [[NEGB]] 628; CHECK-NEXT: ret i32 [[XOR]] 629; 630 %nega = xor i32 %a, -1 631 %negb = xor i32 %b, -1 632 %and = and i32 %negb, %nega 633 %xor = xor i32 %a, %negb 634 %or = or i32 %and, %xor 635 ret i32 %or 636} 637 638; Commute operands of the 'or'. 639; (~A ^ B) | (~A & ~B) -> ~A ^ B 640 641define i32 @test46(i32 %a, i32 %b) { 642; CHECK-LABEL: @test46( 643; CHECK-NEXT: [[NEGB:%.*]] = xor i32 [[B:%.*]], -1 644; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], [[NEGB]] 645; CHECK-NEXT: ret i32 [[XOR]] 646; 647 %nega = xor i32 %a, -1 648 %negb = xor i32 %b, -1 649 %and = and i32 %nega, %negb 650 %xor = xor i32 %a, %negb 651 %or = or i32 %xor, %and 652 ret i32 %or 653} 654 655; (~A & ~B) | (~A ^ B) -> ~A ^ B 656 657define i32 @test46_commuted_and(i32 %a, i32 %b) { 658; CHECK-LABEL: @test46_commuted_and( 659; CHECK-NEXT: [[NEGB:%.*]] = xor i32 [[B:%.*]], -1 660; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], [[NEGB]] 661; CHECK-NEXT: ret i32 [[XOR]] 662; 663 %nega = xor i32 %a, -1 664 %negb = xor i32 %b, -1 665 %and = and i32 %negb, %nega 666 %xor = xor i32 %a, %negb 667 %or = or i32 %xor, %and 668 ret i32 %or 669} 670 671; (~A ^ B) | (A & B) -> ~A ^ B 672 673define i32 @test47(i32 %a, i32 %b) { 674; CHECK-LABEL: @test47( 675; CHECK-NEXT: [[NEGA:%.*]] = xor i32 [[A:%.*]], -1 676; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[NEGA]], [[B:%.*]] 677; CHECK-NEXT: ret i32 [[XOR]] 678; 679 %nega = xor i32 %a, -1 680 %and = and i32 %a, %b 681 %xor = xor i32 %nega, %b 682 %or = or i32 %xor, %and 683 ret i32 %or 684} 685 686define i32 @test48(i32 %a, i32 %b) { 687; CHECK-LABEL: @test48( 688; CHECK-NEXT: [[NEGA:%.*]] = xor i32 [[A:%.*]], -1 689; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[B:%.*]], [[NEGA]] 690; CHECK-NEXT: ret i32 [[XOR]] 691; 692 %nega = xor i32 %a, -1 693 %and = and i32 %a, %b 694 %xor = xor i32 %b, %nega 695 %or = or i32 %xor, %and 696 ret i32 %or 697} 698 699define i32 @test49(i32 %a, i32 %b) { 700; CHECK-LABEL: @test49( 701; CHECK-NEXT: [[NEGA:%.*]] = xor i32 [[A:%.*]], -1 702; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[B:%.*]], [[NEGA]] 703; CHECK-NEXT: ret i32 [[XOR]] 704; 705 %nega = xor i32 %a, -1 706 %and = and i32 %b, %a 707 %xor = xor i32 %b, %nega 708 %or = or i32 %xor, %and 709 ret i32 %or 710} 711 712define i32 @test50(i32 %a, i32 %b) { 713; CHECK-LABEL: @test50( 714; CHECK-NEXT: [[NEGA:%.*]] = xor i32 [[A:%.*]], -1 715; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[NEGA]], [[B:%.*]] 716; CHECK-NEXT: ret i32 [[XOR]] 717; 718 %nega = xor i32 %a, -1 719 %and = and i32 %b, %a 720 %xor = xor i32 %nega, %b 721 %or = or i32 %xor, %and 722 ret i32 %or 723} 724 725define i32 @test51(i32 %a, i32 %b) { 726; CHECK-LABEL: @test51( 727; CHECK-NEXT: [[NEGA:%.*]] = xor i32 [[A:%.*]], -1 728; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[NEGA]], [[B:%.*]] 729; CHECK-NEXT: ret i32 [[XOR]] 730; 731 %nega = xor i32 %a, -1 732 %and = and i32 %a, %b 733 %xor = xor i32 %nega, %b 734 %or = or i32 %and, %xor 735 ret i32 %or 736} 737 738define i32 @test52(i32 %a, i32 %b) { 739; CHECK-LABEL: @test52( 740; CHECK-NEXT: [[NEGA:%.*]] = xor i32 [[A:%.*]], -1 741; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[B:%.*]], [[NEGA]] 742; CHECK-NEXT: ret i32 [[XOR]] 743; 744 %nega = xor i32 %a, -1 745 %and = and i32 %a, %b 746 %xor = xor i32 %b, %nega 747 %or = or i32 %and, %xor 748 ret i32 %or 749} 750 751define i32 @test53(i32 %a, i32 %b) { 752; CHECK-LABEL: @test53( 753; CHECK-NEXT: [[NEGA:%.*]] = xor i32 [[A:%.*]], -1 754; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[B:%.*]], [[NEGA]] 755; CHECK-NEXT: ret i32 [[XOR]] 756; 757 %nega = xor i32 %a, -1 758 %and = and i32 %b, %a 759 %xor = xor i32 %b, %nega 760 %or = or i32 %and, %xor 761 ret i32 %or 762} 763 764define i32 @test54(i32 %a, i32 %b) { 765; CHECK-LABEL: @test54( 766; CHECK-NEXT: [[NEGA:%.*]] = xor i32 [[A:%.*]], -1 767; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[NEGA]], [[B:%.*]] 768; CHECK-NEXT: ret i32 [[XOR]] 769; 770 %nega = xor i32 %a, -1 771 %and = and i32 %b, %a 772 %xor = xor i32 %nega, %b 773 %or = or i32 %and, %xor 774 ret i32 %or 775} 776 777; (A & B) | ~(A ^ B) -> ~(A ^ B) 778 779define i32 @test55(i32 %a, i32 %b) { 780; CHECK-LABEL: @test55( 781; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], [[B:%.*]] 782; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A]], [[B]] 783; CHECK-NEXT: [[XNOR:%.*]] = xor i32 [[XOR]], -1 784; CHECK-NEXT: [[OR:%.*]] = or i32 [[AND]], [[XNOR]] 785; CHECK-NEXT: ret i32 [[OR]] 786; 787 %and = and i32 %a, %b 788 %xor = xor i32 %a, %b 789 %xnor = xor i32 %xor, -1 790 %or = or i32 %and, %xnor 791 ret i32 %or 792} 793 794; ~(A ^ B) | (A & B) -> ~(A ^ B) 795 796define i32 @test56(i32 %a, i32 %b) { 797; CHECK-LABEL: @test56( 798; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], [[B:%.*]] 799; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A]], [[B]] 800; CHECK-NEXT: [[XNOR:%.*]] = xor i32 [[XOR]], -1 801; CHECK-NEXT: [[OR:%.*]] = or i32 [[XNOR]], [[AND]] 802; CHECK-NEXT: ret i32 [[OR]] 803; 804 %and = and i32 %a, %b 805 %xor = xor i32 %a, %b 806 %xnor = xor i32 %xor, -1 807 %or = or i32 %xnor, %and 808 ret i32 %or 809} 810 811; (B & A) | ~(A ^ B) -> ~(A ^ B) 812 813define i32 @test57(i32 %a, i32 %b) { 814; CHECK-LABEL: @test57( 815; CHECK-NEXT: [[AND:%.*]] = and i32 [[B:%.*]], [[A:%.*]] 816; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A]], [[B]] 817; CHECK-NEXT: [[XNOR:%.*]] = xor i32 [[XOR]], -1 818; CHECK-NEXT: [[OR:%.*]] = or i32 [[AND]], [[XNOR]] 819; CHECK-NEXT: ret i32 [[OR]] 820; 821 %and = and i32 %b, %a 822 %xor = xor i32 %a, %b 823 %xnor = xor i32 %xor, -1 824 %or = or i32 %and, %xnor 825 ret i32 %or 826} 827 828; ~(A ^ B) | (A & B) -> ~(A ^ B) 829 830define i32 @test58(i32 %a, i32 %b) { 831; CHECK-LABEL: @test58( 832; CHECK-NEXT: [[AND:%.*]] = and i32 [[B:%.*]], [[A:%.*]] 833; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A]], [[B]] 834; CHECK-NEXT: [[XNOR:%.*]] = xor i32 [[XOR]], -1 835; CHECK-NEXT: [[OR:%.*]] = or i32 [[XNOR]], [[AND]] 836; CHECK-NEXT: ret i32 [[OR]] 837; 838 %and = and i32 %b, %a 839 %xor = xor i32 %a, %b 840 %xnor = xor i32 %xor, -1 841 %or = or i32 %xnor, %and 842 ret i32 %or 843} 844 845define i8 @lshr_perfect_mask(i8 %x) { 846; CHECK-LABEL: @lshr_perfect_mask( 847; CHECK-NEXT: [[SH:%.*]] = lshr i8 [[X:%.*]], 5 848; CHECK-NEXT: ret i8 [[SH]] 849; 850 %sh = lshr i8 %x, 5 851 %mask = and i8 %sh, 7 ; 0x07 852 ret i8 %mask 853} 854 855define <2 x i8> @lshr_oversized_mask_splat(<2 x i8> %x) { 856; CHECK-LABEL: @lshr_oversized_mask_splat( 857; CHECK-NEXT: [[SH:%.*]] = lshr <2 x i8> [[X:%.*]], <i8 5, i8 5> 858; CHECK-NEXT: ret <2 x i8> [[SH]] 859; 860 %sh = lshr <2 x i8> %x, <i8 5, i8 5> 861 %mask = and <2 x i8> %sh, <i8 135, i8 135> ; 0x87 862 ret <2 x i8> %mask 863} 864 865define i8 @lshr_undersized_mask(i8 %x) { 866; CHECK-LABEL: @lshr_undersized_mask( 867; CHECK-NEXT: [[SH:%.*]] = lshr i8 [[X:%.*]], 5 868; CHECK-NEXT: [[MASK:%.*]] = and i8 [[SH]], -2 869; CHECK-NEXT: ret i8 [[MASK]] 870; 871 %sh = lshr i8 %x, 5 872 %mask = and i8 %sh, -2 ; 0xFE 873 ret i8 %mask 874} 875 876define <2 x i8> @shl_perfect_mask_splat(<2 x i8> %x) { 877; CHECK-LABEL: @shl_perfect_mask_splat( 878; CHECK-NEXT: [[SH:%.*]] = shl <2 x i8> [[X:%.*]], <i8 6, i8 6> 879; CHECK-NEXT: ret <2 x i8> [[SH]] 880; 881 %sh = shl <2 x i8> %x, <i8 6, i8 6> 882 %mask = and <2 x i8> %sh, <i8 192, i8 192> ; 0xC0 883 ret <2 x i8> %mask 884} 885 886define i8 @shl_oversized_mask(i8 %x) { 887; CHECK-LABEL: @shl_oversized_mask( 888; CHECK-NEXT: [[SH:%.*]] = shl i8 [[X:%.*]], 6 889; CHECK-NEXT: ret i8 [[SH]] 890; 891 %sh = shl i8 %x, 6 892 %mask = and i8 %sh, 195 ; 0xC3 893 ret i8 %mask 894} 895 896define <2 x i8> @shl_undersized_mask_splat(<2 x i8> %x) { 897; CHECK-LABEL: @shl_undersized_mask_splat( 898; CHECK-NEXT: [[SH:%.*]] = shl <2 x i8> [[X:%.*]], <i8 6, i8 6> 899; CHECK-NEXT: [[MASK:%.*]] = and <2 x i8> [[SH]], <i8 -120, i8 -120> 900; CHECK-NEXT: ret <2 x i8> [[MASK]] 901; 902 %sh = shl <2 x i8> %x, <i8 6, i8 6> 903 %mask = and <2 x i8> %sh, <i8 136, i8 136> ; 0x88 904 ret <2 x i8> %mask 905} 906 907define i32 @reversed_not(i32 %a) { 908; CHECK-LABEL: @reversed_not( 909; CHECK-NEXT: ret i32 -1 910; 911 %nega = xor i32 -1, %a 912 %or = or i32 %a, %nega 913 ret i32 %or 914} 915 916define i64 @shl_or_and1(i32 %a, i1 %b) { 917; CHECK-LABEL: @shl_or_and1( 918; CHECK-NEXT: [[T2:%.*]] = zext i1 [[B:%.*]] to i64 919; CHECK-NEXT: ret i64 [[T2]] 920; 921 %t1 = zext i32 %a to i64 922 %t2 = zext i1 %b to i64 923 %t3 = shl nuw i64 %t1, 32 924 %t4 = or i64 %t2, %t3 925 %t5 = and i64 %t4, 1 926 ret i64 %t5 927} 928 929define i64 @shl_or_and2(i32 %a, i1 %b) { 930; CHECK-LABEL: @shl_or_and2( 931; CHECK-NEXT: [[T1:%.*]] = zext i1 [[B:%.*]] to i64 932; CHECK-NEXT: [[T3:%.*]] = shl nuw i64 [[T1]], 32 933; CHECK-NEXT: ret i64 [[T3]] 934; 935 %t1 = zext i1 %b to i64 936 %t2 = zext i32 %a to i64 937 %t3 = shl nuw i64 %t1, 32 938 %t4 = or i64 %t2, %t3 939 %t5 = and i64 %t4, 4294967296 940 ret i64 %t5 941} 942 943; concatenate two 32-bit integers and extract lower 32-bit 944define i64 @shl_or_and3(i32 %a, i32 %b) { 945; CHECK-LABEL: @shl_or_and3( 946; CHECK-NEXT: [[T2:%.*]] = zext i32 [[B:%.*]] to i64 947; CHECK-NEXT: ret i64 [[T2]] 948; 949 %t1 = zext i32 %a to i64 950 %t2 = zext i32 %b to i64 951 %t3 = shl nuw i64 %t1, 32 952 %t4 = or i64 %t2, %t3 953 %t5 = and i64 %t4, 4294967295 954 ret i64 %t5 955} 956 957; concatenate two 16-bit integers and extract higher 16-bit 958define i32 @shl_or_and4(i16 %a, i16 %b) { 959; CHECK-LABEL: @shl_or_and4( 960; CHECK-NEXT: [[T1:%.*]] = zext i16 [[A:%.*]] to i32 961; CHECK-NEXT: [[T3:%.*]] = shl nuw i32 [[T1]], 16 962; CHECK-NEXT: ret i32 [[T3]] 963; 964 %t1 = zext i16 %a to i32 965 %t2 = zext i16 %b to i32 966 %t3 = shl nuw i32 %t1, 16 967 %t4 = or i32 %t2, %t3 968 %t5 = and i32 %t4, 4294901760 ; mask with 0xFFFF0000 969 ret i32 %t5 970} 971 972define i128 @shl_or_and5(i64 %a, i1 %b) { 973; CHECK-LABEL: @shl_or_and5( 974; CHECK-NEXT: [[T2:%.*]] = zext i1 [[B:%.*]] to i128 975; CHECK-NEXT: ret i128 [[T2]] 976; 977 %t1 = zext i64 %a to i128 978 %t2 = zext i1 %b to i128 979 %t3 = shl nuw i128 %t1, 64 980 %t4 = or i128 %t2, %t3 981 %t5 = and i128 %t4, 1 982 ret i128 %t5 983} 984 985; A variation of above test cases; it fails due to the mask value 986define i32 @shl_or_and6(i16 %a, i16 %b) { 987; CHECK-LABEL: @shl_or_and6( 988; CHECK-NEXT: [[T1:%.*]] = zext i16 [[A:%.*]] to i32 989; CHECK-NEXT: [[T2:%.*]] = zext i16 [[B:%.*]] to i32 990; CHECK-NEXT: [[T3:%.*]] = shl nuw i32 [[T1]], 16 991; CHECK-NEXT: [[T4:%.*]] = or i32 [[T2]], [[T3]] 992; CHECK-NEXT: [[T5:%.*]] = and i32 [[T4]], -65535 993; CHECK-NEXT: ret i32 [[T5]] 994; 995 %t1 = zext i16 %a to i32 996 %t2 = zext i16 %b to i32 997 %t3 = shl nuw i32 %t1, 16 998 %t4 = or i32 %t2, %t3 999 %t5 = and i32 %t4, 4294901761 ; mask with 0xFFFF0001 1000 ret i32 %t5 1001} 1002 1003; A variation of above test cases; it fails due to the mask value 1004define i32 @shl_or_and7(i16 %a, i16 %b) { 1005; CHECK-LABEL: @shl_or_and7( 1006; CHECK-NEXT: [[T1:%.*]] = zext i16 [[A:%.*]] to i32 1007; CHECK-NEXT: [[T2:%.*]] = zext i16 [[B:%.*]] to i32 1008; CHECK-NEXT: [[T3:%.*]] = shl nuw i32 [[T1]], 16 1009; CHECK-NEXT: [[T4:%.*]] = or i32 [[T2]], [[T3]] 1010; CHECK-NEXT: [[T5:%.*]] = and i32 [[T4]], -131072 1011; CHECK-NEXT: ret i32 [[T5]] 1012; 1013 %t1 = zext i16 %a to i32 1014 %t2 = zext i16 %b to i32 1015 %t3 = shl nuw i32 %t1, 16 1016 %t4 = or i32 %t2, %t3 1017 %t5 = and i32 %t4, 4294836224 ; mask with 0xFFFE0000 1018 ret i32 %t5 1019} 1020 1021; A variation of above test cases; it fails due to the mask value 1022define i32 @shl_or_and8(i16 %a, i16 %b) { 1023; CHECK-LABEL: @shl_or_and8( 1024; CHECK-NEXT: [[T1:%.*]] = zext i16 [[A:%.*]] to i32 1025; CHECK-NEXT: [[T2:%.*]] = zext i16 [[B:%.*]] to i32 1026; CHECK-NEXT: [[T3:%.*]] = shl nuw i32 [[T1]], 16 1027; CHECK-NEXT: [[T4:%.*]] = or i32 [[T2]], [[T3]] 1028; CHECK-NEXT: [[T5:%.*]] = and i32 [[T4]], 131071 1029; CHECK-NEXT: ret i32 [[T5]] 1030; 1031 %t1 = zext i16 %a to i32 1032 %t2 = zext i16 %b to i32 1033 %t3 = shl nuw i32 %t1, 16 1034 %t4 = or i32 %t2, %t3 1035 %t5 = and i32 %t4, 131071 ; mask with 0x1FFFF 1036 ret i32 %t5 1037} 1038 1039define <2 x i64> @shl_or_and1v(<2 x i32> %a, <2 x i1> %b) { 1040; CHECK-LABEL: @shl_or_and1v( 1041; CHECK-NEXT: [[T2:%.*]] = zext <2 x i1> [[B:%.*]] to <2 x i64> 1042; CHECK-NEXT: ret <2 x i64> [[T2]] 1043; 1044 %t1 = zext <2 x i32> %a to <2 x i64> 1045 %t2 = zext <2 x i1> %b to <2 x i64> 1046 %t3 = shl nuw <2 x i64> %t1, <i64 32, i64 32> 1047 %t4 = or <2 x i64> %t3, %t2 1048 %t5 = and <2 x i64> %t4, <i64 1, i64 1> 1049 ret <2 x i64> %t5 1050} 1051 1052define <2 x i64> @shl_or_and2v(<2 x i32> %a, <2 x i1> %b) { 1053; CHECK-LABEL: @shl_or_and2v( 1054; CHECK-NEXT: [[T1:%.*]] = zext <2 x i1> [[B:%.*]] to <2 x i64> 1055; CHECK-NEXT: [[T3:%.*]] = shl nuw <2 x i64> [[T1]], <i64 32, i64 32> 1056; CHECK-NEXT: ret <2 x i64> [[T3]] 1057; 1058 %t1 = zext <2 x i1> %b to <2 x i64> 1059 %t2 = zext <2 x i32> %a to <2 x i64> 1060 %t3 = shl nuw <2 x i64> %t1, <i64 32, i64 32> 1061 %t4 = or <2 x i64> %t2, %t3 1062 %t5 = and <2 x i64> %t4, <i64 4294967296, i64 4294967296> 1063 ret <2 x i64> %t5 1064} 1065 1066; A variation of above test case, but fails due to the mask value 1067define <2 x i32> @shl_or_and3v(<2 x i16> %a, <2 x i16> %b) { 1068; CHECK-LABEL: @shl_or_and3v( 1069; CHECK-NEXT: [[T1:%.*]] = zext <2 x i16> [[A:%.*]] to <2 x i32> 1070; CHECK-NEXT: [[T2:%.*]] = zext <2 x i16> [[B:%.*]] to <2 x i32> 1071; CHECK-NEXT: [[T3:%.*]] = shl nuw <2 x i32> [[T1]], <i32 16, i32 16> 1072; CHECK-NEXT: [[T4:%.*]] = or <2 x i32> [[T2]], [[T3]] 1073; CHECK-NEXT: [[T5:%.*]] = and <2 x i32> [[T4]], <i32 -65535, i32 -65535> 1074; CHECK-NEXT: ret <2 x i32> [[T5]] 1075; 1076 %t1 = zext <2 x i16> %a to <2 x i32> 1077 %t2 = zext <2 x i16> %b to <2 x i32> 1078 %t3 = shl nuw <2 x i32> %t1, <i32 16, i32 16> 1079 %t4 = or <2 x i32> %t2, %t3 1080 %t5 = and <2 x i32> %t4, <i32 4294901761, i32 4294901761> ; mask with 0xFFFF0001 1081 ret <2 x i32> %t5 1082} 1083 1084define i8 @and_add_sub(i8 %x) { 1085; CHECK-LABEL: @and_add_sub( 1086; CHECK-NEXT: ret i8 0 1087; 1088 %a = add i8 %x, -1 1089 %s = sub i8 0, %x 1090 %r = and i8 %a, %s 1091 ret i8 %r 1092} 1093 1094define <2 x i8> @and_sub_add(<2 x i8> %x) { 1095; CHECK-LABEL: @and_sub_add( 1096; CHECK-NEXT: ret <2 x i8> zeroinitializer 1097; 1098 %a = add <2 x i8> %x, <i8 -4, i8 -4> 1099 %s = sub <2 x i8> <i8 3, i8 3>, %x 1100 %r = and <2 x i8> %s, %a 1101 ret <2 x i8> %r 1102} 1103 1104define i89 @or_add_sub(i89 %x) { 1105; CHECK-LABEL: @or_add_sub( 1106; CHECK-NEXT: ret i89 -1 1107; 1108 %a = add i89 %x, 5 1109 %s = sub i89 -6, %x 1110 %r = or i89 %a, %s 1111 ret i89 %r 1112} 1113 1114define <3 x i8> @or_sub_add(<3 x i8> %x) { 1115; CHECK-LABEL: @or_sub_add( 1116; CHECK-NEXT: ret <3 x i8> <i8 -1, i8 -1, i8 -1> 1117; 1118 %a = add <3 x i8> %x, <i8 42, i8 -12, i8 0> 1119 %s = sub <3 x i8> <i8 -43, i8 11, i8 -1>, %x 1120 %r = or <3 x i8> %s, %a 1121 ret <3 x i8> %r 1122} 1123 1124 1125define <2 x i17> @xor_add_sub(<2 x i17> %x) { 1126; CHECK-LABEL: @xor_add_sub( 1127; CHECK-NEXT: ret <2 x i17> <i17 -1, i17 -1> 1128; 1129 %a = add <2 x i17> %x, <i17 3000, i17 23> 1130 %s = sub <2 x i17> <i17 -3001, i17 -24>, %x 1131 %r = xor <2 x i17> %a, %s 1132 ret <2 x i17> %r 1133} 1134 1135define i8 @xor_sub_add(i8 %x) { 1136; CHECK-LABEL: @xor_sub_add( 1137; CHECK-NEXT: ret i8 -1 1138; 1139 %a = add i8 %x, 33 1140 %s = sub i8 -34, %x 1141 %r = xor i8 %s, %a 1142 ret i8 %r 1143} 1144 1145; Negative test 1146 1147define i8 @and_add_sub_wrong_const(i8 %x) { 1148; CHECK-LABEL: @and_add_sub_wrong_const( 1149; CHECK-NEXT: [[A:%.*]] = add i8 [[X:%.*]], 6 1150; CHECK-NEXT: [[S:%.*]] = sub i8 -6, [[X]] 1151; CHECK-NEXT: [[R:%.*]] = and i8 [[A]], [[S]] 1152; CHECK-NEXT: ret i8 [[R]] 1153; 1154 %a = add i8 %x, 6 1155 %s = sub i8 -6, %x 1156 %r = and i8 %a, %s 1157 ret i8 %r 1158} 1159 1160; Negative test 1161 1162define i8 @or_add_sub_wrong_var(i8 %x, i8 %y) { 1163; CHECK-LABEL: @or_add_sub_wrong_var( 1164; CHECK-NEXT: [[A:%.*]] = add i8 [[X:%.*]], 5 1165; CHECK-NEXT: [[S:%.*]] = sub i8 -6, [[Y:%.*]] 1166; CHECK-NEXT: [[R:%.*]] = or i8 [[A]], [[S]] 1167; CHECK-NEXT: ret i8 [[R]] 1168; 1169 %a = add i8 %x, 5 1170 %s = sub i8 -6, %y 1171 %r = or i8 %a, %s 1172 ret i8 %r 1173} 1174 1175; Negative test 1176 1177define i8 @xor_add_sub_wrong_op(i8 %x) { 1178; CHECK-LABEL: @xor_add_sub_wrong_op( 1179; CHECK-NEXT: [[A:%.*]] = add i8 [[X:%.*]], 5 1180; CHECK-NEXT: [[S:%.*]] = sub i8 [[X]], -6 1181; CHECK-NEXT: [[R:%.*]] = xor i8 [[A]], [[S]] 1182; CHECK-NEXT: ret i8 [[R]] 1183; 1184 %a = add i8 %x, 5 1185 %s = sub i8 %x, -6 1186 %r = xor i8 %a, %s 1187 ret i8 %r 1188} 1189 1190; `and` isn't needed if it doesn't actually change any bits. 1191define i8 @noop_and_t0(i8 %x) { 1192; CHECK-LABEL: @noop_and_t0( 1193; CHECK-NEXT: [[A:%.*]] = shl i8 [[X:%.*]], 3 1194; CHECK-NEXT: [[B:%.*]] = lshr i8 [[A]], 2 1195; CHECK-NEXT: [[R:%.*]] = and i8 [[B]], 62 1196; CHECK-NEXT: ret i8 [[R]] 1197; 1198 %a = shl i8 %x, 3 1199 %b = lshr i8 %a, 2 1200 %r = and i8 %b, 62 1201 ret i8 %r 1202} 1203define i8 @noop_and_t1(i8 %x) { 1204; CHECK-LABEL: @noop_and_t1( 1205; CHECK-NEXT: [[A:%.*]] = shl i8 [[X:%.*]], 3 1206; CHECK-NEXT: [[B:%.*]] = lshr i8 [[A]], 2 1207; CHECK-NEXT: [[R:%.*]] = and i8 [[B]], 126 1208; CHECK-NEXT: ret i8 [[R]] 1209; 1210 %a = shl i8 %x, 3 1211 %b = lshr i8 %a, 2 1212 %r = and i8 %b, 126 1213 ret i8 %r 1214} 1215