1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 4declare void @use(i8) 5declare void @use_vec(<2 x i8>) 6 7; ((b | a) & C1) | (b & C2) -> (a & C1) | b iff C1 == ~C2 8 9define i32 @or_and_not_constant_commute0(i32 %a, i32 %b) { 10; CHECK-LABEL: @or_and_not_constant_commute0( 11; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[A:%.*]], 1 12; CHECK-NEXT: [[T3:%.*]] = or i32 [[TMP1]], [[B:%.*]] 13; CHECK-NEXT: ret i32 [[T3]] 14; 15 %t = or i32 %b, %a 16 %t1 = and i32 %t, 1 17 %t2 = and i32 %b, -2 18 %t3 = or i32 %t1, %t2 19 ret i32 %t3 20} 21 22define i32 @or_and_not_constant_commute1(i32 %a, i32 %b) { 23; CHECK-LABEL: @or_and_not_constant_commute1( 24; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[A:%.*]], 1 25; CHECK-NEXT: [[T3:%.*]] = or i32 [[TMP1]], [[B:%.*]] 26; CHECK-NEXT: ret i32 [[T3]] 27; 28 %t = or i32 %a, %b 29 %t1 = and i32 1, %t 30 %t2 = and i32 -2, %b 31 %t3 = or i32 %t1, %t2 32 ret i32 %t3 33} 34 35define i32 @or_and_not_constant_commute2(i32 %a, i32 %b) { 36; CHECK-LABEL: @or_and_not_constant_commute2( 37; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[A:%.*]], 1 38; CHECK-NEXT: [[T3:%.*]] = or i32 [[TMP1]], [[B:%.*]] 39; CHECK-NEXT: ret i32 [[T3]] 40; 41 %t = or i32 %b, %a 42 %t1 = and i32 %t, 1 43 %t2 = and i32 %b, -2 44 %t3 = or i32 %t2, %t1 45 ret i32 %t3 46} 47 48define i32 @or_and_not_constant_commute3(i32 %a, i32 %b) { 49; CHECK-LABEL: @or_and_not_constant_commute3( 50; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[A:%.*]], 1 51; CHECK-NEXT: [[T3:%.*]] = or i32 [[TMP1]], [[B:%.*]] 52; CHECK-NEXT: ret i32 [[T3]] 53; 54 %t = or i32 %a, %b 55 %t1 = and i32 1, %t 56 %t2 = and i32 -2, %b 57 %t3 = or i32 %t2, %t1 58 ret i32 %t3 59} 60 61define <2 x i7> @or_and_not_constant_commute0_splat(<2 x i7> %a, <2 x i7> %b) { 62; CHECK-LABEL: @or_and_not_constant_commute0_splat( 63; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i7> [[A:%.*]], splat (i7 42) 64; CHECK-NEXT: [[T3:%.*]] = or <2 x i7> [[TMP1]], [[B:%.*]] 65; CHECK-NEXT: ret <2 x i7> [[T3]] 66; 67 %t = or <2 x i7> %b, %a 68 %t1 = and <2 x i7> %t, <i7 42, i7 42> 69 %t2 = and <2 x i7> %b, <i7 -43, i7 -43> 70 %t3 = or <2 x i7> %t1, %t2 71 ret <2 x i7> %t3 72} 73 74; ((x | N) & C1) | (x & C2) --> (x | N) & (C1 | C2) 75; iff (C1 & C2) == 0 and (N & ~C1) == 0 76 77define i8 @or_and_or_commute0(i8 %x) { 78; CHECK-LABEL: @or_and_or_commute0( 79; CHECK-NEXT: [[XN:%.*]] = or i8 [[X:%.*]], 16 80; CHECK-NEXT: call void @use(i8 [[XN]]) 81; CHECK-NEXT: [[X1:%.*]] = and i8 [[XN]], 59 82; CHECK-NEXT: call void @use(i8 [[X1]]) 83; CHECK-NEXT: [[X2:%.*]] = and i8 [[X]], 64 84; CHECK-NEXT: call void @use(i8 [[X2]]) 85; CHECK-NEXT: [[R:%.*]] = and i8 [[XN]], 123 86; CHECK-NEXT: ret i8 [[R]] 87; 88 %xn = or i8 %x, 16 ; 0001_0000 89 call void @use(i8 %xn) 90 %x1 = and i8 %xn, 59 ; 0011_1011 91 call void @use(i8 %x1) 92 %x2 = and i8 %x, 64 ; 0100_0000 93 call void @use(i8 %x2) 94 %r = or i8 %x1, %x2 95 ret i8 %r 96} 97 98define i8 @or_and_or_commute1(i8 %x) { 99; CHECK-LABEL: @or_and_or_commute1( 100; CHECK-NEXT: [[XN:%.*]] = or i8 [[X:%.*]], 16 101; CHECK-NEXT: call void @use(i8 [[XN]]) 102; CHECK-NEXT: [[X1:%.*]] = and i8 [[XN]], 59 103; CHECK-NEXT: call void @use(i8 [[X1]]) 104; CHECK-NEXT: [[X2:%.*]] = and i8 [[X]], 64 105; CHECK-NEXT: call void @use(i8 [[X2]]) 106; CHECK-NEXT: [[R:%.*]] = and i8 [[XN]], 123 107; CHECK-NEXT: ret i8 [[R]] 108; 109 %xn = or i8 %x, 16 ; 0001_0000 110 call void @use(i8 %xn) 111 %x1 = and i8 %xn, 59 ; 0011_1011 112 call void @use(i8 %x1) 113 %x2 = and i8 %x, 64 ; 0100_0000 114 call void @use(i8 %x2) 115 %r = or i8 %x2, %x1 116 ret i8 %r 117} 118 119define <2 x i8> @or_and_or_commute1_splat(<2 x i8> %x) { 120; CHECK-LABEL: @or_and_or_commute1_splat( 121; CHECK-NEXT: [[XN:%.*]] = or <2 x i8> [[X:%.*]], splat (i8 16) 122; CHECK-NEXT: call void @use_vec(<2 x i8> [[XN]]) 123; CHECK-NEXT: [[X1:%.*]] = and <2 x i8> [[XN]], splat (i8 59) 124; CHECK-NEXT: call void @use_vec(<2 x i8> [[X1]]) 125; CHECK-NEXT: [[X2:%.*]] = and <2 x i8> [[X]], splat (i8 64) 126; CHECK-NEXT: call void @use_vec(<2 x i8> [[X2]]) 127; CHECK-NEXT: [[R:%.*]] = and <2 x i8> [[XN]], splat (i8 123) 128; CHECK-NEXT: ret <2 x i8> [[R]] 129; 130 %xn = or <2 x i8> %x, <i8 16, i8 16> 131 call void @use_vec(<2 x i8> %xn) 132 %x1 = and <2 x i8> %xn, <i8 59, i8 59> 133 call void @use_vec(<2 x i8> %x1) 134 %x2 = and <2 x i8> %x, <i8 64, i8 64> 135 call void @use_vec(<2 x i8> %x2) 136 %r = or <2 x i8> %x2, %x1 137 ret <2 x i8> %r 138} 139 140define i8 @or_and_or_commute2(i8 %x, i8 %y) { 141; CHECK-LABEL: @or_and_or_commute2( 142; CHECK-NEXT: [[N:%.*]] = lshr i8 [[Y:%.*]], 6 143; CHECK-NEXT: [[XN:%.*]] = or i8 [[N]], [[X:%.*]] 144; CHECK-NEXT: call void @use(i8 [[XN]]) 145; CHECK-NEXT: [[X1:%.*]] = and i8 [[XN]], -69 146; CHECK-NEXT: call void @use(i8 [[X1]]) 147; CHECK-NEXT: [[X2:%.*]] = and i8 [[X]], 64 148; CHECK-NEXT: call void @use(i8 [[X2]]) 149; CHECK-NEXT: [[R:%.*]] = and i8 [[XN]], -5 150; CHECK-NEXT: ret i8 [[R]] 151; 152 %n = lshr i8 %y, 6 153 %xn = or i8 %n, %x 154 call void @use(i8 %xn) 155 %x1 = and i8 %xn, 187 156 call void @use(i8 %x1) 157 %x2 = and i8 %x, 64 158 call void @use(i8 %x2) 159 %r = or i8 %x1, %x2 160 ret i8 %r 161} 162 163define <2 x i8> @or_and_or_commute2_splat(<2 x i8> %x, <2 x i8> %y) { 164; CHECK-LABEL: @or_and_or_commute2_splat( 165; CHECK-NEXT: [[N:%.*]] = lshr <2 x i8> [[Y:%.*]], splat (i8 6) 166; CHECK-NEXT: [[XN:%.*]] = or <2 x i8> [[N]], [[X:%.*]] 167; CHECK-NEXT: call void @use_vec(<2 x i8> [[XN]]) 168; CHECK-NEXT: [[X1:%.*]] = and <2 x i8> [[XN]], splat (i8 -69) 169; CHECK-NEXT: call void @use_vec(<2 x i8> [[X1]]) 170; CHECK-NEXT: [[X2:%.*]] = and <2 x i8> [[X]], splat (i8 64) 171; CHECK-NEXT: call void @use_vec(<2 x i8> [[X2]]) 172; CHECK-NEXT: [[R:%.*]] = and <2 x i8> [[XN]], splat (i8 -5) 173; CHECK-NEXT: ret <2 x i8> [[R]] 174; 175 %n = lshr <2 x i8> %y, <i8 6, i8 6> 176 %xn = or <2 x i8> %n, %x 177 call void @use_vec(<2 x i8> %xn) 178 %x1 = and <2 x i8> %xn, <i8 187, i8 187> 179 call void @use_vec(<2 x i8> %x1) 180 %x2 = and <2 x i8> %x, <i8 64, i8 64> 181 call void @use_vec(<2 x i8> %x2) 182 %r = or <2 x i8> %x1, %x2 183 ret <2 x i8> %r 184} 185 186define i8 @or_and_or_commute3(i8 %x, i8 %y) { 187; CHECK-LABEL: @or_and_or_commute3( 188; CHECK-NEXT: [[N:%.*]] = lshr i8 [[Y:%.*]], 6 189; CHECK-NEXT: [[XN:%.*]] = or i8 [[N]], [[X:%.*]] 190; CHECK-NEXT: call void @use(i8 [[XN]]) 191; CHECK-NEXT: [[X1:%.*]] = and i8 [[XN]], -69 192; CHECK-NEXT: call void @use(i8 [[X1]]) 193; CHECK-NEXT: [[X2:%.*]] = and i8 [[X]], 64 194; CHECK-NEXT: call void @use(i8 [[X2]]) 195; CHECK-NEXT: [[R:%.*]] = and i8 [[XN]], -5 196; CHECK-NEXT: ret i8 [[R]] 197; 198 %n = lshr i8 %y, 6 199 %xn = or i8 %n, %x 200 call void @use(i8 %xn) 201 %x1 = and i8 %xn, 187 202 call void @use(i8 %x1) 203 %x2 = and i8 %x, 64 204 call void @use(i8 %x2) 205 %r = or i8 %x2, %x1 206 ret i8 %r 207} 208 209define i8 @or_and2_or2(i8 %x) { 210; CHECK-LABEL: @or_and2_or2( 211; CHECK-NEXT: [[O1:%.*]] = or i8 [[X:%.*]], 1 212; CHECK-NEXT: call void @use(i8 [[O1]]) 213; CHECK-NEXT: [[O2:%.*]] = or i8 [[X]], 2 214; CHECK-NEXT: call void @use(i8 [[O2]]) 215; CHECK-NEXT: [[X1:%.*]] = and i8 [[O1]], -71 216; CHECK-NEXT: call void @use(i8 [[X1]]) 217; CHECK-NEXT: [[X2:%.*]] = and i8 [[O2]], 66 218; CHECK-NEXT: call void @use(i8 [[X2]]) 219; CHECK-NEXT: [[BITFIELD:%.*]] = and i8 [[X]], -8 220; CHECK-NEXT: [[R:%.*]] = or disjoint i8 [[BITFIELD]], 3 221; CHECK-NEXT: ret i8 [[R]] 222; 223 %o1 = or i8 %x, 1 224 call void @use(i8 %o1) 225 %o2 = or i8 %x, 2 226 call void @use(i8 %o2) 227 %x1 = and i8 %o1, 185 228 call void @use(i8 %x1) 229 %x2 = and i8 %o2, 66 230 call void @use(i8 %x2) 231 %r = or i8 %x1, %x2 232 ret i8 %r 233} 234 235define <2 x i8> @or_and2_or2_splat(<2 x i8> %x) { 236; CHECK-LABEL: @or_and2_or2_splat( 237; CHECK-NEXT: [[O1:%.*]] = or <2 x i8> [[X:%.*]], splat (i8 1) 238; CHECK-NEXT: call void @use_vec(<2 x i8> [[O1]]) 239; CHECK-NEXT: [[O2:%.*]] = or <2 x i8> [[X]], splat (i8 2) 240; CHECK-NEXT: call void @use_vec(<2 x i8> [[O2]]) 241; CHECK-NEXT: [[X1:%.*]] = and <2 x i8> [[O1]], splat (i8 -71) 242; CHECK-NEXT: call void @use_vec(<2 x i8> [[X1]]) 243; CHECK-NEXT: [[X2:%.*]] = and <2 x i8> [[O2]], splat (i8 66) 244; CHECK-NEXT: call void @use_vec(<2 x i8> [[X2]]) 245; CHECK-NEXT: [[BITFIELD:%.*]] = and <2 x i8> [[X]], splat (i8 -8) 246; CHECK-NEXT: [[R:%.*]] = or disjoint <2 x i8> [[BITFIELD]], splat (i8 3) 247; CHECK-NEXT: ret <2 x i8> [[R]] 248; 249 %o1 = or <2 x i8> %x, <i8 1, i8 1> 250 call void @use_vec(<2 x i8> %o1) 251 %o2 = or <2 x i8> %x, <i8 2, i8 2> 252 call void @use_vec(<2 x i8> %o2) 253 %x1 = and <2 x i8> %o1, <i8 185, i8 185> 254 call void @use_vec(<2 x i8> %x1) 255 %x2 = and <2 x i8> %o2, <i8 66, i8 66> 256 call void @use_vec(<2 x i8> %x2) 257 %r = or <2 x i8> %x1, %x2 258 ret <2 x i8> %r 259} 260 261; Check variants of: 262; and ({x}or X, Y), C --> {x}or X, (and Y, C) 263; ...in the following 5 tests. 264 265define i8 @and_or_hoist_mask(i8 %a, i8 %b) { 266; CHECK-LABEL: @and_or_hoist_mask( 267; CHECK-NEXT: [[SH:%.*]] = lshr i8 [[A:%.*]], 6 268; CHECK-NEXT: [[B_MASKED:%.*]] = and i8 [[B:%.*]], 3 269; CHECK-NEXT: [[AND:%.*]] = or i8 [[SH]], [[B_MASKED]] 270; CHECK-NEXT: ret i8 [[AND]] 271; 272 %sh = lshr i8 %a, 6 273 %or = or i8 %sh, %b 274 %and = and i8 %or, 3 275 ret i8 %and 276} 277 278define <2 x i8> @and_xor_hoist_mask_vec_splat(<2 x i8> %a, <2 x i8> %b) { 279; CHECK-LABEL: @and_xor_hoist_mask_vec_splat( 280; CHECK-NEXT: [[SH:%.*]] = lshr <2 x i8> [[A:%.*]], splat (i8 6) 281; CHECK-NEXT: [[B_MASKED:%.*]] = and <2 x i8> [[B:%.*]], splat (i8 3) 282; CHECK-NEXT: [[AND:%.*]] = xor <2 x i8> [[SH]], [[B_MASKED]] 283; CHECK-NEXT: ret <2 x i8> [[AND]] 284; 285 %sh = lshr <2 x i8> %a, <i8 6, i8 6> 286 %xor = xor <2 x i8> %sh, %b 287 %and = and <2 x i8> %xor, <i8 3, i8 3> 288 ret <2 x i8> %and 289} 290 291define i8 @and_xor_hoist_mask_commute(i8 %a, i8 %b) { 292; CHECK-LABEL: @and_xor_hoist_mask_commute( 293; CHECK-NEXT: [[C:%.*]] = mul i8 [[B:%.*]], 3 294; CHECK-NEXT: [[SH:%.*]] = lshr i8 [[A:%.*]], 6 295; CHECK-NEXT: [[C_MASKED:%.*]] = and i8 [[C]], 3 296; CHECK-NEXT: [[AND:%.*]] = xor i8 [[C_MASKED]], [[SH]] 297; CHECK-NEXT: ret i8 [[AND]] 298; 299 %c = mul i8 %b, 43 ; thwart complexity-based ordering 300 %sh = lshr i8 %a, 6 301 %xor = xor i8 %c, %sh 302 %and = and i8 %xor, 3 303 ret i8 %and 304} 305 306define <2 x i8> @and_or_hoist_mask_commute_vec_splat(<2 x i8> %a, <2 x i8> %b) { 307; CHECK-LABEL: @and_or_hoist_mask_commute_vec_splat( 308; CHECK-NEXT: [[C:%.*]] = mul <2 x i8> [[B:%.*]], splat (i8 3) 309; CHECK-NEXT: [[SH:%.*]] = lshr <2 x i8> [[A:%.*]], splat (i8 6) 310; CHECK-NEXT: [[C_MASKED:%.*]] = and <2 x i8> [[C]], splat (i8 3) 311; CHECK-NEXT: [[AND:%.*]] = or <2 x i8> [[C_MASKED]], [[SH]] 312; CHECK-NEXT: ret <2 x i8> [[AND]] 313; 314 %c = mul <2 x i8> %b, <i8 43, i8 43> ; thwart complexity-based ordering 315 %sh = lshr <2 x i8> %a, <i8 6, i8 6> 316 %or = or <2 x i8> %c, %sh 317 %and = and <2 x i8> %or, <i8 3, i8 3> 318 ret <2 x i8> %and 319} 320 321@g = external global i32 322 323define i32 @pr64114_and_xor_hoist_mask_constexpr() { 324; CHECK-LABEL: @pr64114_and_xor_hoist_mask_constexpr( 325; CHECK-NEXT: [[LSHR:%.*]] = lshr i32 ptrtoint (ptr @g to i32), 8 326; CHECK-NEXT: [[AND:%.*]] = and i32 [[LSHR]], 1 327; CHECK-NEXT: ret i32 [[AND]] 328; 329 %lshr = lshr i32 ptrtoint (ptr @g to i32), 8 330 %xor = xor i32 %lshr, ptrtoint (ptr @g to i32) 331 %and = and i32 %xor, 1 332 ret i32 %and 333} 334 335; Don't transform if the 'or' has multiple uses because that would increase instruction count. 336 337define i8 @and_or_do_not_hoist_mask(i8 %a, i8 %b) { 338; CHECK-LABEL: @and_or_do_not_hoist_mask( 339; CHECK-NEXT: [[SH:%.*]] = lshr i8 [[A:%.*]], 6 340; CHECK-NEXT: [[OR:%.*]] = or i8 [[SH]], [[B:%.*]] 341; CHECK-NEXT: [[AND:%.*]] = and i8 [[OR]], 3 342; CHECK-NEXT: [[EXTRA_USE_OF_OR:%.*]] = mul i8 [[OR]], [[AND]] 343; CHECK-NEXT: ret i8 [[EXTRA_USE_OF_OR]] 344; 345 %sh = lshr i8 %a, 6 346 %or = or i8 %sh, %b 347 %and = and i8 %or, 3 348 %extra_use_of_or = mul i8 %or, %and 349 ret i8 %extra_use_of_or 350} 351 352define i64 @or_or_and_complex(i64 %i) { 353; CHECK-LABEL: @or_or_and_complex( 354; CHECK-NEXT: [[TMP1:%.*]] = lshr i64 [[I:%.*]], 8 355; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[I]], 8 356; CHECK-NEXT: [[TMP3:%.*]] = and i64 [[TMP1]], 71777214294589695 357; CHECK-NEXT: [[TMP4:%.*]] = and i64 [[TMP2]], -71777214294589696 358; CHECK-NEXT: [[OR27:%.*]] = or disjoint i64 [[TMP3]], [[TMP4]] 359; CHECK-NEXT: ret i64 [[OR27]] 360; 361 %1 = lshr i64 %i, 8 362 %shl = and i64 %1, 71776119061217280 363 %2 = shl i64 %i, 8 364 %shl3 = and i64 %2, -72057594037927936 365 %or = or i64 %shl, %shl3 366 %shl6 = and i64 %1, 1095216660480 367 %or7 = or i64 %or, %shl6 368 %shl10 = and i64 %2, 280375465082880 369 %or11 = or i64 %or7, %shl10 370 %shl14 = and i64 %1, 16711680 371 %or15 = or i64 %or11, %shl14 372 %shl18 = and i64 %2, 4278190080 373 %or19 = or i64 %or15, %shl18 374 %and21 = and i64 %1, 255 375 %or23 = or i64 %or19, %and21 376 %shl26 = and i64 %2, 65280 377 %or27 = or i64 %or23, %shl26 378 ret i64 %or27 379} 380 381; (C | (A & D)) | (A & B) 382define i8 @or_or_and_noOneUse(i8 %a, i8 %b, i8 %c, i8 %d) { 383; CHECK-LABEL: @or_or_and_noOneUse( 384; CHECK-NEXT: [[AND1:%.*]] = and i8 [[A:%.*]], [[B:%.*]] 385; CHECK-NEXT: call void @use(i8 [[AND1]]) 386; CHECK-NEXT: [[AND2:%.*]] = and i8 [[A]], [[D:%.*]] 387; CHECK-NEXT: call void @use(i8 [[AND2]]) 388; CHECK-NEXT: [[OR1:%.*]] = or i8 [[C:%.*]], [[AND2]] 389; CHECK-NEXT: call void @use(i8 [[OR1]]) 390; CHECK-NEXT: [[OR2:%.*]] = or i8 [[OR1]], [[AND1]] 391; CHECK-NEXT: ret i8 [[OR2]] 392; 393 %and1 = and i8 %a, %b 394 call void @use(i8 %and1) 395 %and2 = and i8 %a, %d 396 call void @use(i8 %and2) 397 %or1 = or i8 %c, %and2 398 call void @use(i8 %or1) 399 %or2 = or i8 %or1, %and1 400 ret i8 %or2 401} 402 403; (C | (A & D)) | (A & B) 404define i8 @or_or_and_pat1(i8 %a, i8 %b, i8 %c, i8 %d) { 405; CHECK-LABEL: @or_or_and_pat1( 406; CHECK-NEXT: [[CT:%.*]] = udiv i8 42, [[C:%.*]] 407; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[D:%.*]], [[B:%.*]] 408; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[A:%.*]], [[TMP1]] 409; CHECK-NEXT: [[OR2:%.*]] = or i8 [[CT]], [[TMP2]] 410; CHECK-NEXT: ret i8 [[OR2]] 411; 412 %ct = udiv i8 42, %c ; thwart complexity-based canonicalization 413 %and1 = and i8 %a, %b 414 %and2 = and i8 %a, %d 415 %or1 = or i8 %ct, %and2 416 %or2 = or i8 %or1, %and1 417 ret i8 %or2 418} 419 420; (C | (D & A)) | (A & B) 421define i8 @or_or_and_pat2(i8 %a, i8 %b, i8 %c, i8 %d) { 422; CHECK-LABEL: @or_or_and_pat2( 423; CHECK-NEXT: [[CT:%.*]] = udiv i8 42, [[C:%.*]] 424; CHECK-NEXT: [[AND21:%.*]] = or i8 [[D:%.*]], [[B:%.*]] 425; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[AND21]], [[A:%.*]] 426; CHECK-NEXT: [[OR2:%.*]] = or i8 [[CT]], [[TMP1]] 427; CHECK-NEXT: ret i8 [[OR2]] 428; 429 %ct = udiv i8 42, %c ; thwart complexity-based canonicalization 430 %and1 = and i8 %a, %b 431 %and2 = and i8 %d, %a 432 %or1 = or i8 %ct, %and2 433 %or2 = or i8 %or1, %and1 434 ret i8 %or2 435} 436 437; (C | (B & D)) | (A & B) 438define i8 @or_or_and_pat3(i8 %a, i8 %b, i8 %c, i8 %d) { 439; CHECK-LABEL: @or_or_and_pat3( 440; CHECK-NEXT: [[CT:%.*]] = udiv i8 42, [[C:%.*]] 441; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[D:%.*]], [[A:%.*]] 442; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[B:%.*]], [[TMP1]] 443; CHECK-NEXT: [[OR2:%.*]] = or i8 [[CT]], [[TMP2]] 444; CHECK-NEXT: ret i8 [[OR2]] 445; 446 %ct = udiv i8 42, %c ; thwart complexity-based canonicalization 447 %and1 = and i8 %a, %b 448 %and2 = and i8 %b, %d 449 %or1 = or i8 %ct, %and2 450 %or2 = or i8 %or1, %and1 451 ret i8 %or2 452} 453 454; (C | (D & B)) | (A & B) 455define i8 @or_or_and_pat4(i8 %a, i8 %b, i8 %c, i8 %d) { 456; CHECK-LABEL: @or_or_and_pat4( 457; CHECK-NEXT: [[CT:%.*]] = udiv i8 42, [[C:%.*]] 458; CHECK-NEXT: [[AND21:%.*]] = or i8 [[D:%.*]], [[A:%.*]] 459; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[AND21]], [[B:%.*]] 460; CHECK-NEXT: [[OR2:%.*]] = or i8 [[CT]], [[TMP1]] 461; CHECK-NEXT: ret i8 [[OR2]] 462; 463 %ct = udiv i8 42, %c ; thwart complexity-based canonicalization 464 %and1 = and i8 %a, %b 465 %and2 = and i8 %d, %b 466 %or1 = or i8 %ct, %and2 467 %or2 = or i8 %or1, %and1 468 ret i8 %or2 469} 470 471; ((A & D) | C) | (A & B) 472define i8 @or_or_and_pat5(i8 %a, i8 %b, i8 %c, i8 %d) { 473; CHECK-LABEL: @or_or_and_pat5( 474; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[D:%.*]], [[B:%.*]] 475; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[A:%.*]], [[TMP1]] 476; CHECK-NEXT: [[OR2:%.*]] = or i8 [[TMP2]], [[C:%.*]] 477; CHECK-NEXT: ret i8 [[OR2]] 478; 479 %and1 = and i8 %a, %b 480 %and2 = and i8 %a, %d 481 %or1 = or i8 %and2, %c 482 %or2 = or i8 %or1, %and1 483 ret i8 %or2 484} 485 486; ((D & A) | C) | (A & B) 487define i8 @or_or_and_pat6(i8 %a, i8 %b, i8 %c, i8 %d) { 488; CHECK-LABEL: @or_or_and_pat6( 489; CHECK-NEXT: [[AND21:%.*]] = or i8 [[D:%.*]], [[B:%.*]] 490; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[AND21]], [[A:%.*]] 491; CHECK-NEXT: [[OR2:%.*]] = or i8 [[TMP1]], [[C:%.*]] 492; CHECK-NEXT: ret i8 [[OR2]] 493; 494 %and1 = and i8 %a, %b 495 %and2 = and i8 %d, %a 496 %or1 = or i8 %and2, %c 497 %or2 = or i8 %or1, %and1 498 ret i8 %or2 499} 500 501; ((B & D) | C) | (A & B) 502define i8 @or_or_and_pat7(i8 %a, i8 %b, i8 %c, i8 %d) { 503; CHECK-LABEL: @or_or_and_pat7( 504; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[D:%.*]], [[A:%.*]] 505; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[B:%.*]], [[TMP1]] 506; CHECK-NEXT: [[OR2:%.*]] = or i8 [[TMP2]], [[C:%.*]] 507; CHECK-NEXT: ret i8 [[OR2]] 508; 509 %and1 = and i8 %a, %b 510 %and2 = and i8 %b, %d 511 %or1 = or i8 %and2, %c 512 %or2 = or i8 %or1, %and1 513 ret i8 %or2 514} 515 516; ((D & B) | C) | (A & B) 517define i8 @or_or_and_pat8(i8 %a, i8 %b, i8 %c, i8 %d) { 518; CHECK-LABEL: @or_or_and_pat8( 519; CHECK-NEXT: [[AND21:%.*]] = or i8 [[D:%.*]], [[A:%.*]] 520; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[AND21]], [[B:%.*]] 521; CHECK-NEXT: [[OR2:%.*]] = or i8 [[TMP1]], [[C:%.*]] 522; CHECK-NEXT: ret i8 [[OR2]] 523; 524 %and1 = and i8 %a, %b 525 %and2 = and i8 %d, %b 526 %or1 = or i8 %and2, %c 527 %or2 = or i8 %or1, %and1 528 ret i8 %or2 529} 530 531; (A & B) | (C | (A & D)) 532define i8 @or_and_or_noOneUse(i8 %a, i8 %b, i8 %c, i8 %d) { 533; CHECK-LABEL: @or_and_or_noOneUse( 534; CHECK-NEXT: [[AND1:%.*]] = and i8 [[A:%.*]], [[B:%.*]] 535; CHECK-NEXT: call void @use(i8 [[AND1]]) 536; CHECK-NEXT: [[AND2:%.*]] = and i8 [[A]], [[D:%.*]] 537; CHECK-NEXT: call void @use(i8 [[AND2]]) 538; CHECK-NEXT: [[OR1:%.*]] = or i8 [[C:%.*]], [[AND2]] 539; CHECK-NEXT: call void @use(i8 [[OR1]]) 540; CHECK-NEXT: [[OR2:%.*]] = or i8 [[AND1]], [[OR1]] 541; CHECK-NEXT: ret i8 [[OR2]] 542; 543 %and1 = and i8 %a, %b 544 call void @use(i8 %and1) 545 %and2 = and i8 %a, %d 546 call void @use(i8 %and2) 547 %or1 = or i8 %c, %and2 548 call void @use(i8 %or1) 549 %or2 = or i8 %and1, %or1 550 ret i8 %or2 551} 552 553; (A & B) | (C | (A & D)) 554define i8 @or_and_or_pat1(i8 %a, i8 %b, i8 %c, i8 %d) { 555; CHECK-LABEL: @or_and_or_pat1( 556; CHECK-NEXT: [[CT:%.*]] = udiv i8 42, [[C:%.*]] 557; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[D:%.*]], [[B:%.*]] 558; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[A:%.*]], [[TMP1]] 559; CHECK-NEXT: [[OR2:%.*]] = or i8 [[CT]], [[TMP2]] 560; CHECK-NEXT: ret i8 [[OR2]] 561; 562 %ct = udiv i8 42, %c ; thwart complexity-based canonicalization 563 %and1 = and i8 %a, %b 564 %and2 = and i8 %a, %d 565 %or1 = or i8 %ct, %and2 566 %or2 = or i8 %and1, %or1 567 ret i8 %or2 568} 569 570; (A & B) | (C | (D & A)) 571define i8 @or_and_or_pat2(i8 %a, i8 %b, i8 %c, i8 %d) { 572; CHECK-LABEL: @or_and_or_pat2( 573; CHECK-NEXT: [[CT:%.*]] = udiv i8 42, [[C:%.*]] 574; CHECK-NEXT: [[AND21:%.*]] = or i8 [[D:%.*]], [[B:%.*]] 575; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[AND21]], [[A:%.*]] 576; CHECK-NEXT: [[OR2:%.*]] = or i8 [[CT]], [[TMP1]] 577; CHECK-NEXT: ret i8 [[OR2]] 578; 579 %ct = udiv i8 42, %c ; thwart complexity-based canonicalization 580 %and1 = and i8 %a, %b 581 %and2 = and i8 %d, %a 582 %or1 = or i8 %ct, %and2 583 %or2 = or i8 %and1, %or1 584 ret i8 %or2 585} 586 587; (A & B) | (C | (B & D)) 588define i8 @or_and_or_pat3(i8 %a, i8 %b, i8 %c, i8 %d) { 589; CHECK-LABEL: @or_and_or_pat3( 590; CHECK-NEXT: [[CT:%.*]] = udiv i8 42, [[C:%.*]] 591; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[D:%.*]], [[A:%.*]] 592; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[B:%.*]], [[TMP1]] 593; CHECK-NEXT: [[OR2:%.*]] = or i8 [[CT]], [[TMP2]] 594; CHECK-NEXT: ret i8 [[OR2]] 595; 596 %ct = udiv i8 42, %c ; thwart complexity-based canonicalization 597 %and1 = and i8 %a, %b 598 %and2 = and i8 %b, %d 599 %or1 = or i8 %ct, %and2 600 %or2 = or i8 %and1, %or1 601 ret i8 %or2 602} 603 604; (A & B) | (C | (D & B)) 605define i8 @or_and_or_pat4(i8 %a, i8 %b, i8 %c, i8 %d) { 606; CHECK-LABEL: @or_and_or_pat4( 607; CHECK-NEXT: [[CT:%.*]] = udiv i8 42, [[C:%.*]] 608; CHECK-NEXT: [[AND21:%.*]] = or i8 [[D:%.*]], [[A:%.*]] 609; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[AND21]], [[B:%.*]] 610; CHECK-NEXT: [[OR2:%.*]] = or i8 [[CT]], [[TMP1]] 611; CHECK-NEXT: ret i8 [[OR2]] 612; 613 %ct = udiv i8 42, %c ; thwart complexity-based canonicalization 614 %and1 = and i8 %a, %b 615 %and2 = and i8 %d, %b 616 %or1 = or i8 %ct, %and2 617 %or2 = or i8 %and1, %or1 618 ret i8 %or2 619} 620 621; (A & B) | ((A & D) | C) 622define i8 @or_and_or_pat5(i8 %a, i8 %b, i8 %c, i8 %d) { 623; CHECK-LABEL: @or_and_or_pat5( 624; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[D:%.*]], [[B:%.*]] 625; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[A:%.*]], [[TMP1]] 626; CHECK-NEXT: [[OR2:%.*]] = or i8 [[TMP2]], [[C:%.*]] 627; CHECK-NEXT: ret i8 [[OR2]] 628; 629 %and1 = and i8 %a, %b 630 %and2 = and i8 %a, %d 631 %or1 = or i8 %and2, %c 632 %or2 = or i8 %and1, %or1 633 ret i8 %or2 634} 635 636; (A & B) | ((D & A) | C) 637define i8 @or_and_or_pat6(i8 %a, i8 %b, i8 %c, i8 %d) { 638; CHECK-LABEL: @or_and_or_pat6( 639; CHECK-NEXT: [[AND21:%.*]] = or i8 [[D:%.*]], [[B:%.*]] 640; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[AND21]], [[A:%.*]] 641; CHECK-NEXT: [[OR2:%.*]] = or i8 [[TMP1]], [[C:%.*]] 642; CHECK-NEXT: ret i8 [[OR2]] 643; 644 %and1 = and i8 %a, %b 645 %and2 = and i8 %d, %a 646 %or1 = or i8 %and2, %c 647 %or2 = or i8 %and1, %or1 648 ret i8 %or2 649} 650 651; (A & B) | ((B & D) | C) 652define i8 @or_and_or_pat7(i8 %a, i8 %b, i8 %c, i8 %d) { 653; CHECK-LABEL: @or_and_or_pat7( 654; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[D:%.*]], [[A:%.*]] 655; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[B:%.*]], [[TMP1]] 656; CHECK-NEXT: [[OR2:%.*]] = or i8 [[TMP2]], [[C:%.*]] 657; CHECK-NEXT: ret i8 [[OR2]] 658; 659 %and1 = and i8 %a, %b 660 %and2 = and i8 %b, %d 661 %or1 = or i8 %and2, %c 662 %or2 = or i8 %and1, %or1 663 ret i8 %or2 664} 665 666; (A & B) | ((D & B) | C) 667define i8 @or_and_or_pat8(i8 %a, i8 %b, i8 %c, i8 %d) { 668; CHECK-LABEL: @or_and_or_pat8( 669; CHECK-NEXT: [[AND21:%.*]] = or i8 [[D:%.*]], [[A:%.*]] 670; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[AND21]], [[B:%.*]] 671; CHECK-NEXT: [[OR2:%.*]] = or i8 [[TMP1]], [[C:%.*]] 672; CHECK-NEXT: ret i8 [[OR2]] 673; 674 %and1 = and i8 %a, %b 675 %and2 = and i8 %d, %b 676 %or1 = or i8 %and2, %c 677 %or2 = or i8 %and1, %or1 678 ret i8 %or2 679} 680 681declare void @use2(i32) 682 683define i32 @or_or_and_noOneUse_fail1(i32 %a, i32 %b) { 684; CHECK-LABEL: @or_or_and_noOneUse_fail1( 685; CHECK-NEXT: [[SHR:%.*]] = ashr i32 [[A:%.*]], 23 686; CHECK-NEXT: [[AND:%.*]] = and i32 [[SHR]], 157 687; CHECK-NEXT: call void @use2(i32 [[AND]]) 688; CHECK-NEXT: [[AND1:%.*]] = or i32 [[B:%.*]], 157 689; CHECK-NEXT: [[OR:%.*]] = and i32 [[SHR]], [[AND1]] 690; CHECK-NEXT: [[SHR8:%.*]] = lshr i32 [[B]], 23 691; CHECK-NEXT: [[AND9:%.*]] = and i32 [[SHR8]], 157 692; CHECK-NEXT: [[R:%.*]] = or i32 [[OR]], [[AND9]] 693; CHECK-NEXT: ret i32 [[R]] 694; 695 %shr = ashr i32 %a, 23 696 %conv = trunc i32 %shr to i8 697 %conv1 = zext i8 %conv to i32 698 %and = and i32 %conv1, 925 699 call void @use2(i32 %and) 700 %and3 = and i32 %shr, %b 701 %or = or i32 %and3, %and 702 %shr8 = ashr i32 %b, 23 703 %and9 = and i32 %shr8, 157 704 %r = or i32 %or, %and9 705 ret i32 %r 706} 707 708define { i1, i1, i1, i1, i1 } @or_or_and_noOneUse_fail2(i1 %a_0, i1 %a_1, i1 %a_2, i1 %a_3, i1 %b_0, i1 %b_1, i1 %b_2, i1 %b_3) { 709; CHECK-LABEL: @or_or_and_noOneUse_fail2( 710; CHECK-NEXT: entry: 711; CHECK-NEXT: [[TMP0:%.*]] = and i1 [[A_0:%.*]], [[B_0:%.*]] 712; CHECK-NEXT: [[TMP1:%.*]] = and i1 [[A_3:%.*]], [[B_3:%.*]] 713; CHECK-NEXT: [[TMP2:%.*]] = xor i1 [[A_2:%.*]], [[B_2:%.*]] 714; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[A_1:%.*]], [[B_1:%.*]] 715; CHECK-NEXT: [[TMP4:%.*]] = xor i1 [[TMP3]], true 716; CHECK-NEXT: [[TMP5:%.*]] = and i1 [[TMP0]], [[A_1]] 717; CHECK-NEXT: [[TMP6:%.*]] = or i1 [[A_1]], [[TMP2]] 718; CHECK-NEXT: [[TMP7:%.*]] = and i1 [[TMP6]], [[B_1]] 719; CHECK-NEXT: [[D:%.*]] = or i1 [[TMP7]], [[TMP5]] 720; CHECK-NEXT: [[DOTNOT1:%.*]] = or i1 [[TMP1]], [[TMP3]] 721; CHECK-NEXT: [[TMP8:%.*]] = insertvalue { i1, i1, i1, i1, i1 } zeroinitializer, i1 [[D]], 0 722; CHECK-NEXT: [[TMP9:%.*]] = insertvalue { i1, i1, i1, i1, i1 } [[TMP8]], i1 [[TMP4]], 1 723; CHECK-NEXT: [[TMP10:%.*]] = insertvalue { i1, i1, i1, i1, i1 } [[TMP9]], i1 true, 2 724; CHECK-NEXT: [[TMP11:%.*]] = insertvalue { i1, i1, i1, i1, i1 } [[TMP10]], i1 [[A_3]], 3 725; CHECK-NEXT: [[TMP12:%.*]] = insertvalue { i1, i1, i1, i1, i1 } [[TMP11]], i1 [[DOTNOT1]], 4 726; CHECK-NEXT: ret { i1, i1, i1, i1, i1 } [[TMP12]] 727; 728entry: 729 %0 = and i1 %a_0, %b_0 730 %1 = and i1 %a_3, %b_3 731 %2 = xor i1 %a_2, %b_2 732 %3 = and i1 %a_1, %b_1 733 %4 = xor i1 %3, true 734 %5 = and i1 %0, %a_1 735 %6 = and i1 %2, %b_1 736 %7 = or i1 %3, %6 737 %d = or i1 %7, %5 738 %8 = xor i1 %d, true 739 %9 = xor i1 %8, true 740 %10 = xor i1 %1, true 741 %11 = and i1 %10, %4 742 %12 = xor i1 %11, true 743 %13 = insertvalue { i1, i1, i1, i1, i1 } zeroinitializer, i1 %9, 0 744 %14 = insertvalue { i1, i1, i1, i1, i1 } %13, i1 %4, 1 745 %15 = insertvalue { i1, i1, i1, i1, i1 } %14, i1 true, 2 746 %16 = insertvalue { i1, i1, i1, i1, i1 } %15, i1 %a_3, 3 747 %17 = insertvalue { i1, i1, i1, i1, i1 } %16, i1 %12, 4 748 ret { i1, i1, i1, i1, i1 } %17 749} 750