1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -instcombine -S | FileCheck %s 3 4target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" 5 6define i32 @test12(i32 %A) { 7 ; Should be eliminated 8; CHECK-LABEL: @test12( 9; CHECK-NEXT: [[C:%.*]] = and i32 [[A:%.*]], 8 10; CHECK-NEXT: ret i32 [[C]] 11; 12 %B = or i32 %A, 4 13 %C = and i32 %B, 8 14 ret i32 %C 15} 16 17define i32 @test13(i32 %A) { 18; CHECK-LABEL: @test13( 19; CHECK-NEXT: ret i32 8 20; 21 %B = or i32 %A, 12 22 ; Always equal to 8 23 %C = and i32 %B, 8 24 ret i32 %C 25} 26 27define i1 @test14(i32 %A, i32 %B) { 28; CHECK-LABEL: @test14( 29; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]] 30; CHECK-NEXT: ret i1 [[TMP1]] 31; 32 %C1 = icmp ult i32 %A, %B 33 %C2 = icmp ugt i32 %A, %B 34 ; (A < B) | (A > B) === A != B 35 %D = or i1 %C1, %C2 36 ret i1 %D 37} 38 39define i1 @test15(i32 %A, i32 %B) { 40; CHECK-LABEL: @test15( 41; CHECK-NEXT: [[TMP1:%.*]] = icmp ule i32 [[A:%.*]], [[B:%.*]] 42; CHECK-NEXT: ret i1 [[TMP1]] 43; 44 %C1 = icmp ult i32 %A, %B 45 %C2 = icmp eq i32 %A, %B 46 ; (A < B) | (A == B) === A <= B 47 %D = or i1 %C1, %C2 48 ret i1 %D 49} 50 51define i32 @test16(i32 %A) { 52; CHECK-LABEL: @test16( 53; CHECK-NEXT: ret i32 [[A:%.*]] 54; 55 %B = and i32 %A, 1 56 ; -2 = ~1 57 %C = and i32 %A, -2 58 ; %D = and int %B, -1 == %B 59 %D = or i32 %B, %C 60 ret i32 %D 61} 62 63define i32 @test17(i32 %A) { 64; CHECK-LABEL: @test17( 65; CHECK-NEXT: [[D:%.*]] = and i32 [[A:%.*]], 5 66; CHECK-NEXT: ret i32 [[D]] 67; 68 %B = and i32 %A, 1 69 %C = and i32 %A, 4 70 ; %D = and int %B, 5 71 %D = or i32 %B, %C 72 ret i32 %D 73} 74 75define i1 @test18(i32 %A) { 76; CHECK-LABEL: @test18( 77; CHECK-NEXT: [[A_OFF:%.*]] = add i32 [[A:%.*]], -50 78; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[A_OFF]], 49 79; CHECK-NEXT: ret i1 [[TMP1]] 80; 81 %B = icmp sge i32 %A, 100 82 %C = icmp slt i32 %A, 50 83 %D = or i1 %B, %C 84 ret i1 %D 85} 86 87; FIXME: Vectors should fold too. 88define <2 x i1> @test18vec(<2 x i32> %A) { 89; CHECK-LABEL: @test18vec( 90; CHECK-NEXT: [[B:%.*]] = icmp sgt <2 x i32> [[A:%.*]], <i32 99, i32 99> 91; CHECK-NEXT: [[C:%.*]] = icmp slt <2 x i32> [[A]], <i32 50, i32 50> 92; CHECK-NEXT: [[D:%.*]] = or <2 x i1> [[B]], [[C]] 93; CHECK-NEXT: ret <2 x i1> [[D]] 94; 95 %B = icmp sge <2 x i32> %A, <i32 100, i32 100> 96 %C = icmp slt <2 x i32> %A, <i32 50, i32 50> 97 %D = or <2 x i1> %B, %C 98 ret <2 x i1> %D 99} 100 101define i32 @test20(i32 %x) { 102; CHECK-LABEL: @test20( 103; CHECK-NEXT: ret i32 [[X:%.*]] 104; 105 %y = and i32 %x, 123 106 %z = or i32 %y, %x 107 ret i32 %z 108} 109 110define i32 @test21(i32 %tmp.1) { 111; CHECK-LABEL: @test21( 112; CHECK-NEXT: [[TMP_1_MASK1:%.*]] = add i32 [[TMP_1:%.*]], 2 113; CHECK-NEXT: ret i32 [[TMP_1_MASK1]] 114; 115 %tmp.1.mask1 = add i32 %tmp.1, 2 116 %tmp.3 = and i32 %tmp.1.mask1, -2 117 %tmp.5 = and i32 %tmp.1, 1 118 ;; add tmp.1, 2 119 %tmp.6 = or i32 %tmp.5, %tmp.3 120 ret i32 %tmp.6 121} 122 123define i32 @test22(i32 %B) { 124; CHECK-LABEL: @test22( 125; CHECK-NEXT: ret i32 [[B:%.*]] 126; 127 %ELIM41 = and i32 %B, 1 128 %ELIM7 = and i32 %B, -2 129 %ELIM5 = or i32 %ELIM41, %ELIM7 130 ret i32 %ELIM5 131} 132 133define i16 @test23(i16 %A) { 134; CHECK-LABEL: @test23( 135; CHECK-NEXT: [[B:%.*]] = lshr i16 [[A:%.*]], 1 136; CHECK-NEXT: [[D:%.*]] = xor i16 [[B]], -24575 137; CHECK-NEXT: ret i16 [[D]] 138; 139 %B = lshr i16 %A, 1 140 ;; fold or into xor 141 %C = or i16 %B, -32768 142 %D = xor i16 %C, 8193 143 ret i16 %D 144} 145 146define <2 x i16> @test23vec(<2 x i16> %A) { 147; CHECK-LABEL: @test23vec( 148; CHECK-NEXT: [[B:%.*]] = lshr <2 x i16> [[A:%.*]], <i16 1, i16 1> 149; CHECK-NEXT: [[D:%.*]] = xor <2 x i16> [[B]], <i16 -24575, i16 -24575> 150; CHECK-NEXT: ret <2 x i16> [[D]] 151; 152 %B = lshr <2 x i16> %A, <i16 1, i16 1> 153 ;; fold or into xor 154 %C = or <2 x i16> %B, <i16 -32768, i16 -32768> 155 %D = xor <2 x i16> %C, <i16 8193, i16 8193> 156 ret <2 x i16> %D 157} 158 159; PR3266 & PR5276 160define i1 @test25(i32 %A, i32 %B) { 161; CHECK-LABEL: @test25( 162; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[A:%.*]], 0 163; CHECK-NEXT: [[D:%.*]] = icmp ne i32 [[B:%.*]], 57 164; CHECK-NEXT: [[F:%.*]] = and i1 [[D]], [[C]] 165; CHECK-NEXT: ret i1 [[F]] 166; 167 %C = icmp eq i32 %A, 0 168 %D = icmp eq i32 %B, 57 169 %E = or i1 %C, %D 170 %F = xor i1 %E, -1 171 ret i1 %F 172} 173 174; PR5634 175define i1 @test26(i32 %A, i32 %B) { 176; CHECK-LABEL: @test26( 177; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[A:%.*]], [[B:%.*]] 178; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0 179; CHECK-NEXT: ret i1 [[TMP2]] 180; 181 %C1 = icmp eq i32 %A, 0 182 %C2 = icmp eq i32 %B, 0 183 ; (A == 0) & (A == 0) --> (A|B) == 0 184 %D = and i1 %C1, %C2 185 ret i1 %D 186} 187 188define i1 @test27(i32* %A, i32* %B) { 189; CHECK-LABEL: @test27( 190; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32* [[A:%.*]], null 191; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32* [[B:%.*]], null 192; CHECK-NEXT: [[E:%.*]] = and i1 [[TMP1]], [[TMP2]] 193; CHECK-NEXT: ret i1 [[E]] 194; 195 %C1 = ptrtoint i32* %A to i32 196 %C2 = ptrtoint i32* %B to i32 197 %D = or i32 %C1, %C2 198 %E = icmp eq i32 %D, 0 199 ret i1 %E 200} 201 202define <2 x i1> @test27vec(<2 x i32*> %A, <2 x i32*> %B) { 203; CHECK-LABEL: @test27vec( 204; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i32*> [[A:%.*]], zeroinitializer 205; CHECK-NEXT: [[TMP2:%.*]] = icmp eq <2 x i32*> [[B:%.*]], zeroinitializer 206; CHECK-NEXT: [[E:%.*]] = and <2 x i1> [[TMP1]], [[TMP2]] 207; CHECK-NEXT: ret <2 x i1> [[E]] 208; 209 %C1 = ptrtoint <2 x i32*> %A to <2 x i32> 210 %C2 = ptrtoint <2 x i32*> %B to <2 x i32> 211 %D = or <2 x i32> %C1, %C2 212 %E = icmp eq <2 x i32> %D, zeroinitializer 213 ret <2 x i1> %E 214} 215 216; PR5634 217define i1 @test28(i32 %A, i32 %B) { 218; CHECK-LABEL: @test28( 219; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[A:%.*]], [[B:%.*]] 220; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0 221; CHECK-NEXT: ret i1 [[TMP2]] 222; 223 %C1 = icmp ne i32 %A, 0 224 %C2 = icmp ne i32 %B, 0 225 ; (A != 0) | (A != 0) --> (A|B) != 0 226 %D = or i1 %C1, %C2 227 ret i1 %D 228} 229 230define i1 @test29(i32* %A, i32* %B) { 231; CHECK-LABEL: @test29( 232; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i32* [[A:%.*]], null 233; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32* [[B:%.*]], null 234; CHECK-NEXT: [[E:%.*]] = or i1 [[TMP1]], [[TMP2]] 235; CHECK-NEXT: ret i1 [[E]] 236; 237 %C1 = ptrtoint i32* %A to i32 238 %C2 = ptrtoint i32* %B to i32 239 %D = or i32 %C1, %C2 240 %E = icmp ne i32 %D, 0 241 ret i1 %E 242} 243 244define <2 x i1> @test29vec(<2 x i32*> %A, <2 x i32*> %B) { 245; CHECK-LABEL: @test29vec( 246; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <2 x i32*> [[A:%.*]], zeroinitializer 247; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x i32*> [[B:%.*]], zeroinitializer 248; CHECK-NEXT: [[E:%.*]] = or <2 x i1> [[TMP1]], [[TMP2]] 249; CHECK-NEXT: ret <2 x i1> [[E]] 250; 251 %C1 = ptrtoint <2 x i32*> %A to <2 x i32> 252 %C2 = ptrtoint <2 x i32*> %B to <2 x i32> 253 %D = or <2 x i32> %C1, %C2 254 %E = icmp ne <2 x i32> %D, zeroinitializer 255 ret <2 x i1> %E 256} 257 258; PR4216 259define i32 @test30(i32 %A) { 260; CHECK-LABEL: @test30( 261; CHECK-NEXT: [[D:%.*]] = and i32 [[A:%.*]], -58312 262; CHECK-NEXT: [[E:%.*]] = or i32 [[D]], 32962 263; CHECK-NEXT: ret i32 [[E]] 264; 265 %B = or i32 %A, 32962 266 %C = and i32 %A, -65536 267 %D = and i32 %B, 40186 268 %E = or i32 %D, %C 269 ret i32 %E 270} 271 272define <2 x i32> @test30vec(<2 x i32> %A) { 273; CHECK-LABEL: @test30vec( 274; CHECK-NEXT: [[C:%.*]] = and <2 x i32> [[A:%.*]], <i32 -65536, i32 -65536> 275; CHECK-NEXT: [[B:%.*]] = and <2 x i32> [[A]], <i32 7224, i32 7224> 276; CHECK-NEXT: [[D:%.*]] = or <2 x i32> [[B]], <i32 32962, i32 32962> 277; CHECK-NEXT: [[E:%.*]] = or <2 x i32> [[D]], [[C]] 278; CHECK-NEXT: ret <2 x i32> [[E]] 279; 280 %B = or <2 x i32> %A, <i32 32962, i32 32962> 281 %C = and <2 x i32> %A, <i32 -65536, i32 -65536> 282 %D = and <2 x i32> %B, <i32 40186, i32 40186> 283 %E = or <2 x i32> %D, %C 284 ret <2 x i32> %E 285} 286 287; PR4216 288define i64 @test31(i64 %A) { 289; CHECK-LABEL: @test31( 290; CHECK-NEXT: [[E:%.*]] = and i64 [[A:%.*]], 4294908984 291; CHECK-NEXT: [[F:%.*]] = or i64 [[E]], 32962 292; CHECK-NEXT: ret i64 [[F]] 293; 294 %B = or i64 %A, 194 295 %D = and i64 %B, 250 296 297 %C = or i64 %A, 32768 298 %E = and i64 %C, 4294941696 299 300 %F = or i64 %D, %E 301 ret i64 %F 302} 303 304define <2 x i64> @test31vec(<2 x i64> %A) { 305; CHECK-LABEL: @test31vec( 306; CHECK-NEXT: [[E:%.*]] = and <2 x i64> [[A:%.*]], <i64 4294908984, i64 4294908984> 307; CHECK-NEXT: [[F:%.*]] = or <2 x i64> [[E]], <i64 32962, i64 32962> 308; CHECK-NEXT: ret <2 x i64> [[F]] 309; 310 %B = or <2 x i64> %A, <i64 194, i64 194> 311 %D = and <2 x i64> %B, <i64 250, i64 250> 312 313 %C = or <2 x i64> %A, <i64 32768, i64 32768> 314 %E = and <2 x i64> %C, <i64 4294941696, i64 4294941696> 315 316 %F = or <2 x i64> %D, %E 317 ret <2 x i64> %F 318} 319 320; codegen is mature enough to handle vector selects. 321define <4 x i32> @test32(<4 x i1> %and.i1352, <4 x i32> %vecinit6.i176, <4 x i32> %vecinit6.i191) { 322; CHECK-LABEL: @test32( 323; CHECK-NEXT: [[TMP1:%.*]] = select <4 x i1> [[AND_I1352:%.*]], <4 x i32> [[VECINIT6_I176:%.*]], <4 x i32> [[VECINIT6_I191:%.*]] 324; CHECK-NEXT: ret <4 x i32> [[TMP1]] 325; 326 %and.i135 = sext <4 x i1> %and.i1352 to <4 x i32> 327 %and.i129 = and <4 x i32> %vecinit6.i176, %and.i135 328 %neg.i = xor <4 x i32> %and.i135, <i32 -1, i32 -1, i32 -1, i32 -1> 329 %and.i = and <4 x i32> %vecinit6.i191, %neg.i 330 %or.i = or <4 x i32> %and.i, %and.i129 331 ret <4 x i32> %or.i 332} 333 334define i1 @test33(i1 %X, i1 %Y) { 335; CHECK-LABEL: @test33( 336; CHECK-NEXT: [[B:%.*]] = or i1 [[X:%.*]], [[Y:%.*]] 337; CHECK-NEXT: ret i1 [[B]] 338; 339 %a = or i1 %X, %Y 340 %b = or i1 %a, %X 341 ret i1 %b 342} 343 344define i32 @test34(i32 %X, i32 %Y) { 345; CHECK-LABEL: @test34( 346; CHECK-NEXT: [[B:%.*]] = or i32 [[X:%.*]], [[Y:%.*]] 347; CHECK-NEXT: ret i32 [[B]] 348; 349 %a = or i32 %X, %Y 350 %b = or i32 %Y, %a 351 ret i32 %b 352} 353 354define i32 @test35(i32 %a, i32 %b) { 355; CHECK-LABEL: @test35( 356; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[A:%.*]], [[B:%.*]] 357; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], 1135 358; CHECK-NEXT: ret i32 [[TMP2]] 359; 360 %1 = or i32 %a, 1135 361 %2 = or i32 %1, %b 362 ret i32 %2 363} 364 365define i1 @test36(i32 %x) { 366; CHECK-LABEL: @test36( 367; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -23 368; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[TMP1]], 3 369; CHECK-NEXT: ret i1 [[TMP2]] 370; 371 %cmp1 = icmp eq i32 %x, 23 372 %cmp2 = icmp eq i32 %x, 24 373 %ret1 = or i1 %cmp1, %cmp2 374 %cmp3 = icmp eq i32 %x, 25 375 %ret2 = or i1 %ret1, %cmp3 376 ret i1 %ret2 377} 378 379define i32 @orsext_to_sel(i32 %x, i1 %y) { 380; CHECK-LABEL: @orsext_to_sel( 381; CHECK-NEXT: [[OR:%.*]] = select i1 [[Y:%.*]], i32 -1, i32 [[X:%.*]] 382; CHECK-NEXT: ret i32 [[OR]] 383; 384 %sext = sext i1 %y to i32 385 %or = or i32 %sext, %x 386 ret i32 %or 387} 388 389define i32 @orsext_to_sel_swap(i32 %x, i1 %y) { 390; CHECK-LABEL: @orsext_to_sel_swap( 391; CHECK-NEXT: [[OR:%.*]] = select i1 [[Y:%.*]], i32 -1, i32 [[X:%.*]] 392; CHECK-NEXT: ret i32 [[OR]] 393; 394 %sext = sext i1 %y to i32 395 %or = or i32 %x, %sext 396 ret i32 %or 397} 398 399define i32 @orsext_to_sel_multi_use(i32 %x, i1 %y) { 400; CHECK-LABEL: @orsext_to_sel_multi_use( 401; CHECK-NEXT: [[SEXT:%.*]] = sext i1 [[Y:%.*]] to i32 402; CHECK-NEXT: [[OR:%.*]] = or i32 [[SEXT]], [[X:%.*]] 403; CHECK-NEXT: [[ADD:%.*]] = add i32 [[OR]], [[SEXT]] 404; CHECK-NEXT: ret i32 [[ADD]] 405; 406 %sext = sext i1 %y to i32 407 %or = or i32 %sext, %x 408 %add = add i32 %sext, %or 409 ret i32 %add 410} 411 412define <2 x i32> @orsext_to_sel_vec(<2 x i32> %x, <2 x i1> %y) { 413; CHECK-LABEL: @orsext_to_sel_vec( 414; CHECK-NEXT: [[OR:%.*]] = select <2 x i1> [[Y:%.*]], <2 x i32> <i32 -1, i32 -1>, <2 x i32> [[X:%.*]] 415; CHECK-NEXT: ret <2 x i32> [[OR]] 416; 417 %sext = sext <2 x i1> %y to <2 x i32> 418 %or = or <2 x i32> %sext, %x 419 ret <2 x i32> %or 420} 421 422define <2 x i132> @orsext_to_sel_vec_swap(<2 x i132> %x, <2 x i1> %y) { 423; CHECK-LABEL: @orsext_to_sel_vec_swap( 424; CHECK-NEXT: [[OR:%.*]] = select <2 x i1> [[Y:%.*]], <2 x i132> <i132 -1, i132 -1>, <2 x i132> [[X:%.*]] 425; CHECK-NEXT: ret <2 x i132> [[OR]] 426; 427 %sext = sext <2 x i1> %y to <2 x i132> 428 %or = or <2 x i132> %x, %sext 429 ret <2 x i132> %or 430} 431 432; (~A & B) | A --> A | B 433 434define i32 @test39a(i32 %a, float %b) { 435; CHECK-LABEL: @test39a( 436; CHECK-NEXT: [[A1:%.*]] = mul i32 [[A:%.*]], 42 437; CHECK-NEXT: [[B1:%.*]] = bitcast float [[B:%.*]] to i32 438; CHECK-NEXT: [[OR:%.*]] = or i32 [[A1]], [[B1]] 439; CHECK-NEXT: ret i32 [[OR]] 440; 441 %a1 = mul i32 %a, 42 ; thwart complexity-based ordering 442 %b1 = bitcast float %b to i32 ; thwart complexity-based ordering 443 %nota = xor i32 %a1, -1 444 %and = and i32 %nota, %b1 445 %or = or i32 %and, %a1 446 ret i32 %or 447} 448 449; Commute 'and' operands: 450; (B & ~A) | A --> A | B 451 452define i32 @test39b(i32 %a, float %b) { 453; CHECK-LABEL: @test39b( 454; CHECK-NEXT: [[A1:%.*]] = mul i32 [[A:%.*]], 42 455; CHECK-NEXT: [[B1:%.*]] = bitcast float [[B:%.*]] to i32 456; CHECK-NEXT: [[OR:%.*]] = or i32 [[A1]], [[B1]] 457; CHECK-NEXT: ret i32 [[OR]] 458; 459 %a1 = mul i32 %a, 42 ; thwart complexity-based ordering 460 %b1 = bitcast float %b to i32 ; thwart complexity-based ordering 461 %nota = xor i32 %a1, -1 462 %and = and i32 %b1, %nota 463 %or = or i32 %and, %a1 464 ret i32 %or 465} 466 467; Commute 'or' operands: 468; A | (~A & B) --> A | B 469 470define i32 @test39c(i32 %a, float %b) { 471; CHECK-LABEL: @test39c( 472; CHECK-NEXT: [[A1:%.*]] = mul i32 [[A:%.*]], 42 473; CHECK-NEXT: [[B1:%.*]] = bitcast float [[B:%.*]] to i32 474; CHECK-NEXT: [[OR:%.*]] = or i32 [[A1]], [[B1]] 475; CHECK-NEXT: ret i32 [[OR]] 476; 477 %a1 = mul i32 %a, 42 ; thwart complexity-based ordering 478 %b1 = bitcast float %b to i32 ; thwart complexity-based ordering 479 %nota = xor i32 %a1, -1 480 %and = and i32 %nota, %b1 481 %or = or i32 %a1, %and 482 ret i32 %or 483} 484 485; Commute 'and' operands: 486; A | (B & ~A) --> A | B 487 488define i32 @test39d(i32 %a, float %b) { 489; CHECK-LABEL: @test39d( 490; CHECK-NEXT: [[A1:%.*]] = mul i32 [[A:%.*]], 42 491; CHECK-NEXT: [[B1:%.*]] = bitcast float [[B:%.*]] to i32 492; CHECK-NEXT: [[OR:%.*]] = or i32 [[A1]], [[B1]] 493; CHECK-NEXT: ret i32 [[OR]] 494; 495 %a1 = mul i32 %a, 42 ; thwart complexity-based ordering 496 %b1 = bitcast float %b to i32 ; thwart complexity-based ordering 497 %nota = xor i32 %a1, -1 498 %and = and i32 %b1, %nota 499 %or = or i32 %a1, %and 500 ret i32 %or 501} 502 503define i32 @test40(i32 %a, i32 %b) { 504; CHECK-LABEL: @test40( 505; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], -1 506; CHECK-NEXT: [[OR:%.*]] = or i32 [[XOR]], [[B:%.*]] 507; CHECK-NEXT: ret i32 [[OR]] 508; 509 %and = and i32 %a, %b 510 %xor = xor i32 %a, -1 511 %or = or i32 %and, %xor 512 ret i32 %or 513} 514 515define i32 @test40b(i32 %a, i32 %b) { 516; CHECK-LABEL: @test40b( 517; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], -1 518; CHECK-NEXT: [[OR:%.*]] = or i32 [[XOR]], [[B:%.*]] 519; CHECK-NEXT: ret i32 [[OR]] 520; 521 %and = and i32 %b, %a 522 %xor = xor i32 %a, -1 523 %or = or i32 %and, %xor 524 ret i32 %or 525} 526 527define i32 @test40c(i32 %a, i32 %b) { 528; CHECK-LABEL: @test40c( 529; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], -1 530; CHECK-NEXT: [[OR:%.*]] = or i32 [[XOR]], [[B:%.*]] 531; CHECK-NEXT: ret i32 [[OR]] 532; 533 %and = and i32 %b, %a 534 %xor = xor i32 %a, -1 535 %or = or i32 %xor, %and 536 ret i32 %or 537} 538 539define i32 @test40d(i32 %a, i32 %b) { 540; CHECK-LABEL: @test40d( 541; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], -1 542; CHECK-NEXT: [[OR:%.*]] = or i32 [[XOR]], [[B:%.*]] 543; CHECK-NEXT: ret i32 [[OR]] 544; 545 %and = and i32 %a, %b 546 %xor = xor i32 %a, -1 547 %or = or i32 %xor, %and 548 ret i32 %or 549} 550 551define i32 @test45(i32 %x, i32 %y, i32 %z) { 552; CHECK-LABEL: @test45( 553; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], [[Z:%.*]] 554; CHECK-NEXT: [[OR1:%.*]] = or i32 [[TMP1]], [[Y:%.*]] 555; CHECK-NEXT: ret i32 [[OR1]] 556; 557 %or = or i32 %y, %z 558 %and = and i32 %x, %or 559 %or1 = or i32 %and, %y 560 ret i32 %or1 561} 562 563define i1 @test46(i8 signext %c) { 564; CHECK-LABEL: @test46( 565; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[C:%.*]], -33 566; CHECK-NEXT: [[TMP2:%.*]] = add i8 [[TMP1]], -65 567; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i8 [[TMP2]], 26 568; CHECK-NEXT: ret i1 [[TMP3]] 569; 570 %c.off = add i8 %c, -97 571 %cmp1 = icmp ult i8 %c.off, 26 572 %c.off17 = add i8 %c, -65 573 %cmp2 = icmp ult i8 %c.off17, 26 574 %or = or i1 %cmp1, %cmp2 575 ret i1 %or 576} 577 578define i1 @test47(i8 signext %c) { 579; CHECK-LABEL: @test47( 580; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[C:%.*]], -33 581; CHECK-NEXT: [[TMP2:%.*]] = add i8 [[TMP1]], -65 582; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i8 [[TMP2]], 27 583; CHECK-NEXT: ret i1 [[TMP3]] 584; 585 %c.off = add i8 %c, -65 586 %cmp1 = icmp ule i8 %c.off, 26 587 %c.off17 = add i8 %c, -97 588 %cmp2 = icmp ule i8 %c.off17, 26 589 %or = or i1 %cmp1, %cmp2 590 ret i1 %or 591} 592 593define i32 @test49(i1 %C) { 594; CHECK-LABEL: @test49( 595; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], i32 1019, i32 123 596; CHECK-NEXT: ret i32 [[V]] 597; 598 %A = select i1 %C, i32 1000, i32 10 599 %V = or i32 %A, 123 600 ret i32 %V 601} 602 603define <2 x i32> @test49vec(i1 %C) { 604; CHECK-LABEL: @test49vec( 605; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 1019, i32 1019>, <2 x i32> <i32 123, i32 123> 606; CHECK-NEXT: ret <2 x i32> [[V]] 607; 608 %A = select i1 %C, <2 x i32> <i32 1000, i32 1000>, <2 x i32> <i32 10, i32 10> 609 %V = or <2 x i32> %A, <i32 123, i32 123> 610 ret <2 x i32> %V 611} 612 613define <2 x i32> @test49vec2(i1 %C) { 614; CHECK-LABEL: @test49vec2( 615; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 1019, i32 2509>, <2 x i32> <i32 123, i32 351> 616; CHECK-NEXT: ret <2 x i32> [[V]] 617; 618 %A = select i1 %C, <2 x i32> <i32 1000, i32 2500>, <2 x i32> <i32 10, i32 30> 619 %V = or <2 x i32> %A, <i32 123, i32 333> 620 ret <2 x i32> %V 621} 622 623define i32 @test50(i1 %which) { 624; CHECK-LABEL: @test50( 625; CHECK-NEXT: entry: 626; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]] 627; CHECK: delay: 628; CHECK-NEXT: br label [[FINAL]] 629; CHECK: final: 630; CHECK-NEXT: [[A:%.*]] = phi i32 [ 1019, [[ENTRY:%.*]] ], [ 123, [[DELAY]] ] 631; CHECK-NEXT: ret i32 [[A]] 632; 633entry: 634 br i1 %which, label %final, label %delay 635 636delay: 637 br label %final 638 639final: 640 %A = phi i32 [ 1000, %entry ], [ 10, %delay ] 641 %value = or i32 %A, 123 642 ret i32 %value 643} 644 645define <2 x i32> @test50vec(i1 %which) { 646; CHECK-LABEL: @test50vec( 647; CHECK-NEXT: entry: 648; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]] 649; CHECK: delay: 650; CHECK-NEXT: br label [[FINAL]] 651; CHECK: final: 652; CHECK-NEXT: [[A:%.*]] = phi <2 x i32> [ <i32 1019, i32 1019>, [[ENTRY:%.*]] ], [ <i32 123, i32 123>, [[DELAY]] ] 653; CHECK-NEXT: ret <2 x i32> [[A]] 654; 655entry: 656 br i1 %which, label %final, label %delay 657 658delay: 659 br label %final 660 661final: 662 %A = phi <2 x i32> [ <i32 1000, i32 1000>, %entry ], [ <i32 10, i32 10>, %delay ] 663 %value = or <2 x i32> %A, <i32 123, i32 123> 664 ret <2 x i32> %value 665} 666 667define <2 x i32> @test50vec2(i1 %which) { 668; CHECK-LABEL: @test50vec2( 669; CHECK-NEXT: entry: 670; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]] 671; CHECK: delay: 672; CHECK-NEXT: br label [[FINAL]] 673; CHECK: final: 674; CHECK-NEXT: [[A:%.*]] = phi <2 x i32> [ <i32 1019, i32 2509>, [[ENTRY:%.*]] ], [ <i32 123, i32 351>, [[DELAY]] ] 675; CHECK-NEXT: ret <2 x i32> [[A]] 676; 677entry: 678 br i1 %which, label %final, label %delay 679 680delay: 681 br label %final 682 683final: 684 %A = phi <2 x i32> [ <i32 1000, i32 2500>, %entry ], [ <i32 10, i32 30>, %delay ] 685 %value = or <2 x i32> %A, <i32 123, i32 333> 686 ret <2 x i32> %value 687} 688 689; In the next 4 tests, vary the types and predicates for extra coverage. 690; (X | (Y & ~X)) -> (X | Y), where 'not' is an inverted cmp 691 692define i1 @or_andn_cmp_1(i32 %a, i32 %b, i32 %c) { 693; CHECK-LABEL: @or_andn_cmp_1( 694; CHECK-NEXT: [[X:%.*]] = icmp sgt i32 [[A:%.*]], [[B:%.*]] 695; CHECK-NEXT: [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 42 696; CHECK-NEXT: [[OR:%.*]] = or i1 [[X]], [[Y]] 697; CHECK-NEXT: ret i1 [[OR]] 698; 699 %x = icmp sgt i32 %a, %b 700 %x_inv = icmp sle i32 %a, %b 701 %y = icmp ugt i32 %c, 42 ; thwart complexity-based ordering 702 %and = and i1 %y, %x_inv 703 %or = or i1 %x, %and 704 ret i1 %or 705} 706 707; Commute the 'or': 708; ((Y & ~X) | X) -> (X | Y), where 'not' is an inverted cmp 709 710define <2 x i1> @or_andn_cmp_2(<2 x i32> %a, <2 x i32> %b, <2 x i32> %c) { 711; CHECK-LABEL: @or_andn_cmp_2( 712; CHECK-NEXT: [[X:%.*]] = icmp sge <2 x i32> [[A:%.*]], [[B:%.*]] 713; CHECK-NEXT: [[Y:%.*]] = icmp ugt <2 x i32> [[C:%.*]], <i32 42, i32 47> 714; CHECK-NEXT: [[OR:%.*]] = or <2 x i1> [[Y]], [[X]] 715; CHECK-NEXT: ret <2 x i1> [[OR]] 716; 717 %x = icmp sge <2 x i32> %a, %b 718 %x_inv = icmp slt <2 x i32> %a, %b 719 %y = icmp ugt <2 x i32> %c, <i32 42, i32 47> ; thwart complexity-based ordering 720 %and = and <2 x i1> %y, %x_inv 721 %or = or <2 x i1> %and, %x 722 ret <2 x i1> %or 723} 724 725; Commute the 'and': 726; (X | (~X & Y)) -> (X | Y), where 'not' is an inverted cmp 727 728define i1 @or_andn_cmp_3(i72 %a, i72 %b, i72 %c) { 729; CHECK-LABEL: @or_andn_cmp_3( 730; CHECK-NEXT: [[X:%.*]] = icmp ugt i72 [[A:%.*]], [[B:%.*]] 731; CHECK-NEXT: [[Y:%.*]] = icmp ugt i72 [[C:%.*]], 42 732; CHECK-NEXT: [[OR:%.*]] = or i1 [[X]], [[Y]] 733; CHECK-NEXT: ret i1 [[OR]] 734; 735 %x = icmp ugt i72 %a, %b 736 %x_inv = icmp ule i72 %a, %b 737 %y = icmp ugt i72 %c, 42 ; thwart complexity-based ordering 738 %and = and i1 %x_inv, %y 739 %or = or i1 %x, %and 740 ret i1 %or 741} 742 743; Commute the 'or': 744; ((~X & Y) | X) -> (X | Y), where 'not' is an inverted cmp 745 746define <3 x i1> @or_andn_cmp_4(<3 x i32> %a, <3 x i32> %b, <3 x i32> %c) { 747; CHECK-LABEL: @or_andn_cmp_4( 748; CHECK-NEXT: [[X:%.*]] = icmp eq <3 x i32> [[A:%.*]], [[B:%.*]] 749; CHECK-NEXT: [[Y:%.*]] = icmp ugt <3 x i32> [[C:%.*]], <i32 42, i32 43, i32 -1> 750; CHECK-NEXT: [[OR:%.*]] = or <3 x i1> [[Y]], [[X]] 751; CHECK-NEXT: ret <3 x i1> [[OR]] 752; 753 %x = icmp eq <3 x i32> %a, %b 754 %x_inv = icmp ne <3 x i32> %a, %b 755 %y = icmp ugt <3 x i32> %c, <i32 42, i32 43, i32 -1> ; thwart complexity-based ordering 756 %and = and <3 x i1> %x_inv, %y 757 %or = or <3 x i1> %and, %x 758 ret <3 x i1> %or 759} 760 761; In the next 4 tests, vary the types and predicates for extra coverage. 762; (~X | (Y & X)) -> (~X | Y), where 'not' is an inverted cmp 763 764define i1 @orn_and_cmp_1(i37 %a, i37 %b, i37 %c) { 765; CHECK-LABEL: @orn_and_cmp_1( 766; CHECK-NEXT: [[X_INV:%.*]] = icmp sle i37 [[A:%.*]], [[B:%.*]] 767; CHECK-NEXT: [[Y:%.*]] = icmp ugt i37 [[C:%.*]], 42 768; CHECK-NEXT: [[OR:%.*]] = or i1 [[X_INV]], [[Y]] 769; CHECK-NEXT: ret i1 [[OR]] 770; 771 %x = icmp sgt i37 %a, %b 772 %x_inv = icmp sle i37 %a, %b 773 %y = icmp ugt i37 %c, 42 ; thwart complexity-based ordering 774 %and = and i1 %y, %x 775 %or = or i1 %x_inv, %and 776 ret i1 %or 777} 778 779; Commute the 'or': 780; ((Y & X) | ~X) -> (~X | Y), where 'not' is an inverted cmp 781 782define i1 @orn_and_cmp_2(i16 %a, i16 %b, i16 %c) { 783; CHECK-LABEL: @orn_and_cmp_2( 784; CHECK-NEXT: [[X_INV:%.*]] = icmp slt i16 [[A:%.*]], [[B:%.*]] 785; CHECK-NEXT: [[Y:%.*]] = icmp ugt i16 [[C:%.*]], 42 786; CHECK-NEXT: [[OR:%.*]] = or i1 [[Y]], [[X_INV]] 787; CHECK-NEXT: ret i1 [[OR]] 788; 789 %x = icmp sge i16 %a, %b 790 %x_inv = icmp slt i16 %a, %b 791 %y = icmp ugt i16 %c, 42 ; thwart complexity-based ordering 792 %and = and i1 %y, %x 793 %or = or i1 %and, %x_inv 794 ret i1 %or 795} 796 797; Commute the 'and': 798; (~X | (X & Y)) -> (~X | Y), where 'not' is an inverted cmp 799 800define <4 x i1> @orn_and_cmp_3(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) { 801; CHECK-LABEL: @orn_and_cmp_3( 802; CHECK-NEXT: [[X_INV:%.*]] = icmp ule <4 x i32> [[A:%.*]], [[B:%.*]] 803; CHECK-NEXT: [[Y:%.*]] = icmp ugt <4 x i32> [[C:%.*]], <i32 42, i32 0, i32 1, i32 -1> 804; CHECK-NEXT: [[OR:%.*]] = or <4 x i1> [[X_INV]], [[Y]] 805; CHECK-NEXT: ret <4 x i1> [[OR]] 806; 807 %x = icmp ugt <4 x i32> %a, %b 808 %x_inv = icmp ule <4 x i32> %a, %b 809 %y = icmp ugt <4 x i32> %c, <i32 42, i32 0, i32 1, i32 -1> ; thwart complexity-based ordering 810 %and = and <4 x i1> %x, %y 811 %or = or <4 x i1> %x_inv, %and 812 ret <4 x i1> %or 813} 814 815; Commute the 'or': 816; ((X & Y) | ~X) -> (~X | Y), where 'not' is an inverted cmp 817 818define i1 @orn_and_cmp_4(i32 %a, i32 %b, i32 %c) { 819; CHECK-LABEL: @orn_and_cmp_4( 820; CHECK-NEXT: [[X_INV:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]] 821; CHECK-NEXT: [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 42 822; CHECK-NEXT: [[OR:%.*]] = or i1 [[Y]], [[X_INV]] 823; CHECK-NEXT: ret i1 [[OR]] 824; 825 %x = icmp eq i32 %a, %b 826 %x_inv = icmp ne i32 %a, %b 827 %y = icmp ugt i32 %c, 42 ; thwart complexity-based ordering 828 %and = and i1 %x, %y 829 %or = or i1 %and, %x_inv 830 ret i1 %or 831} 832 833; The constant vectors are inverses. Make sure we can turn this into a select without crashing trying to truncate the constant to 16xi1. 834define <16 x i1> @test51(<16 x i1> %arg, <16 x i1> %arg1) { 835; CHECK-LABEL: @test51( 836; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <16 x i1> [[ARG:%.*]], <16 x i1> [[ARG1:%.*]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 20, i32 5, i32 6, i32 23, i32 24, i32 9, i32 10, i32 27, i32 28, i32 29, i32 30, i32 31> 837; CHECK-NEXT: ret <16 x i1> [[TMP1]] 838; 839 %tmp = and <16 x i1> %arg, <i1 true, i1 true, i1 true, i1 true, i1 false, i1 true, i1 true, i1 false, i1 false, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false, i1 false> 840 %tmp2 = and <16 x i1> %arg1, <i1 false, i1 false, i1 false, i1 false, i1 true, i1 false, i1 false, i1 true, i1 true, i1 false, i1 false, i1 true, i1 true, i1 true, i1 true, i1 true> 841 %tmp3 = or <16 x i1> %tmp, %tmp2 842 ret <16 x i1> %tmp3 843} 844