750 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4declare void @use(i8)5declare void @use_vec(<2 x i8>)6 7; ((b | a) & C1) | (b & C2) -> (a & C1) | b iff C1 == ~C28 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:%.*]], 112; CHECK-NEXT: [[T3:%.*]] = or i32 [[TMP1]], [[B:%.*]]13; CHECK-NEXT: ret i32 [[T3]]14;15 %t = or i32 %b, %a16 %t1 = and i32 %t, 117 %t2 = and i32 %b, -218 %t3 = or i32 %t1, %t219 ret i32 %t320}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:%.*]], 125; CHECK-NEXT: [[T3:%.*]] = or i32 [[TMP1]], [[B:%.*]]26; CHECK-NEXT: ret i32 [[T3]]27;28 %t = or i32 %a, %b29 %t1 = and i32 1, %t30 %t2 = and i32 -2, %b31 %t3 = or i32 %t1, %t232 ret i32 %t333}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:%.*]], 138; CHECK-NEXT: [[T3:%.*]] = or i32 [[TMP1]], [[B:%.*]]39; CHECK-NEXT: ret i32 [[T3]]40;41 %t = or i32 %b, %a42 %t1 = and i32 %t, 143 %t2 = and i32 %b, -244 %t3 = or i32 %t2, %t145 ret i32 %t346}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:%.*]], 151; CHECK-NEXT: [[T3:%.*]] = or i32 [[TMP1]], [[B:%.*]]52; CHECK-NEXT: ret i32 [[T3]]53;54 %t = or i32 %a, %b55 %t1 = and i32 1, %t56 %t2 = and i32 -2, %b57 %t3 = or i32 %t2, %t158 ret i32 %t359}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, %a68 %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, %t271 ret <2 x i7> %t372}73 74; ((x | N) & C1) | (x & C2) --> (x | N) & (C1 | C2)75; iff (C1 & C2) == 0 and (N & ~C1) == 076 77define i8 @or_and_or_commute0(i8 %x) {78; CHECK-LABEL: @or_and_or_commute0(79; CHECK-NEXT: [[XN:%.*]] = or i8 [[X:%.*]], 1680; CHECK-NEXT: call void @use(i8 [[XN]])81; CHECK-NEXT: [[X1:%.*]] = and i8 [[XN]], 5982; CHECK-NEXT: call void @use(i8 [[X1]])83; CHECK-NEXT: [[X2:%.*]] = and i8 [[X]], 6484; CHECK-NEXT: call void @use(i8 [[X2]])85; CHECK-NEXT: [[R:%.*]] = and i8 [[XN]], 12386; CHECK-NEXT: ret i8 [[R]]87;88 %xn = or i8 %x, 16 ; 0001_000089 call void @use(i8 %xn)90 %x1 = and i8 %xn, 59 ; 0011_101191 call void @use(i8 %x1)92 %x2 = and i8 %x, 64 ; 0100_000093 call void @use(i8 %x2)94 %r = or i8 %x1, %x295 ret i8 %r96}97 98define i8 @or_and_or_commute1(i8 %x) {99; CHECK-LABEL: @or_and_or_commute1(100; CHECK-NEXT: [[XN:%.*]] = or i8 [[X:%.*]], 16101; CHECK-NEXT: call void @use(i8 [[XN]])102; CHECK-NEXT: [[X1:%.*]] = and i8 [[XN]], 59103; CHECK-NEXT: call void @use(i8 [[X1]])104; CHECK-NEXT: [[X2:%.*]] = and i8 [[X]], 64105; CHECK-NEXT: call void @use(i8 [[X2]])106; CHECK-NEXT: [[R:%.*]] = and i8 [[XN]], 123107; CHECK-NEXT: ret i8 [[R]]108;109 %xn = or i8 %x, 16 ; 0001_0000110 call void @use(i8 %xn)111 %x1 = and i8 %xn, 59 ; 0011_1011112 call void @use(i8 %x1)113 %x2 = and i8 %x, 64 ; 0100_0000114 call void @use(i8 %x2)115 %r = or i8 %x2, %x1116 ret i8 %r117}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, %x1137 ret <2 x i8> %r138}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:%.*]], 6143; CHECK-NEXT: [[XN:%.*]] = or i8 [[N]], [[X:%.*]]144; CHECK-NEXT: call void @use(i8 [[XN]])145; CHECK-NEXT: [[X1:%.*]] = and i8 [[XN]], -69146; CHECK-NEXT: call void @use(i8 [[X1]])147; CHECK-NEXT: [[X2:%.*]] = and i8 [[X]], 64148; CHECK-NEXT: call void @use(i8 [[X2]])149; CHECK-NEXT: [[R:%.*]] = and i8 [[XN]], -5150; CHECK-NEXT: ret i8 [[R]]151;152 %n = lshr i8 %y, 6153 %xn = or i8 %n, %x154 call void @use(i8 %xn)155 %x1 = and i8 %xn, 187156 call void @use(i8 %x1)157 %x2 = and i8 %x, 64158 call void @use(i8 %x2)159 %r = or i8 %x1, %x2160 ret i8 %r161}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, %x177 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, %x2183 ret <2 x i8> %r184}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:%.*]], 6189; CHECK-NEXT: [[XN:%.*]] = or i8 [[N]], [[X:%.*]]190; CHECK-NEXT: call void @use(i8 [[XN]])191; CHECK-NEXT: [[X1:%.*]] = and i8 [[XN]], -69192; CHECK-NEXT: call void @use(i8 [[X1]])193; CHECK-NEXT: [[X2:%.*]] = and i8 [[X]], 64194; CHECK-NEXT: call void @use(i8 [[X2]])195; CHECK-NEXT: [[R:%.*]] = and i8 [[XN]], -5196; CHECK-NEXT: ret i8 [[R]]197;198 %n = lshr i8 %y, 6199 %xn = or i8 %n, %x200 call void @use(i8 %xn)201 %x1 = and i8 %xn, 187202 call void @use(i8 %x1)203 %x2 = and i8 %x, 64204 call void @use(i8 %x2)205 %r = or i8 %x2, %x1206 ret i8 %r207}208 209define i8 @or_and2_or2(i8 %x) {210; CHECK-LABEL: @or_and2_or2(211; CHECK-NEXT: [[O1:%.*]] = or i8 [[X:%.*]], 1212; CHECK-NEXT: call void @use(i8 [[O1]])213; CHECK-NEXT: [[O2:%.*]] = or i8 [[X]], 2214; CHECK-NEXT: call void @use(i8 [[O2]])215; CHECK-NEXT: [[X1:%.*]] = and i8 [[O1]], -71216; CHECK-NEXT: call void @use(i8 [[X1]])217; CHECK-NEXT: [[X2:%.*]] = and i8 [[O2]], 66218; CHECK-NEXT: call void @use(i8 [[X2]])219; CHECK-NEXT: [[BITFIELD:%.*]] = and i8 [[X]], -8220; CHECK-NEXT: [[R:%.*]] = or disjoint i8 [[BITFIELD]], 3221; CHECK-NEXT: ret i8 [[R]]222;223 %o1 = or i8 %x, 1224 call void @use(i8 %o1)225 %o2 = or i8 %x, 2226 call void @use(i8 %o2)227 %x1 = and i8 %o1, 185228 call void @use(i8 %x1)229 %x2 = and i8 %o2, 66230 call void @use(i8 %x2)231 %r = or i8 %x1, %x2232 ret i8 %r233}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, %x2258 ret <2 x i8> %r259}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:%.*]], 6268; CHECK-NEXT: [[B_MASKED:%.*]] = and i8 [[B:%.*]], 3269; CHECK-NEXT: [[AND:%.*]] = or i8 [[SH]], [[B_MASKED]]270; CHECK-NEXT: ret i8 [[AND]]271;272 %sh = lshr i8 %a, 6273 %or = or i8 %sh, %b274 %and = and i8 %or, 3275 ret i8 %and276}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, %b287 %and = and <2 x i8> %xor, <i8 3, i8 3>288 ret <2 x i8> %and289}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:%.*]], 3294; CHECK-NEXT: [[SH:%.*]] = lshr i8 [[A:%.*]], 6295; CHECK-NEXT: [[C_MASKED:%.*]] = and i8 [[C]], 3296; CHECK-NEXT: [[AND:%.*]] = xor i8 [[C_MASKED]], [[SH]]297; CHECK-NEXT: ret i8 [[AND]]298;299 %c = mul i8 %b, 43 ; thwart complexity-based ordering300 %sh = lshr i8 %a, 6301 %xor = xor i8 %c, %sh302 %and = and i8 %xor, 3303 ret i8 %and304}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 ordering315 %sh = lshr <2 x i8> %a, <i8 6, i8 6>316 %or = or <2 x i8> %c, %sh317 %and = and <2 x i8> %or, <i8 3, i8 3>318 ret <2 x i8> %and319}320 321@g = external global i32322 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), 8326; CHECK-NEXT: [[AND:%.*]] = and i32 [[LSHR]], 1327; CHECK-NEXT: ret i32 [[AND]]328;329 %lshr = lshr i32 ptrtoint (ptr @g to i32), 8330 %xor = xor i32 %lshr, ptrtoint (ptr @g to i32)331 %and = and i32 %xor, 1332 ret i32 %and333}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:%.*]], 6340; CHECK-NEXT: [[OR:%.*]] = or i8 [[SH]], [[B:%.*]]341; CHECK-NEXT: [[AND:%.*]] = and i8 [[OR]], 3342; 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, 6346 %or = or i8 %sh, %b347 %and = and i8 %or, 3348 %extra_use_of_or = mul i8 %or, %and349 ret i8 %extra_use_of_or350}351 352define i64 @or_or_and_complex(i64 %i) {353; CHECK-LABEL: @or_or_and_complex(354; CHECK-NEXT: [[TMP1:%.*]] = lshr i64 [[I:%.*]], 8355; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[I]], 8356; CHECK-NEXT: [[TMP3:%.*]] = and i64 [[TMP1]], 71777214294589695357; CHECK-NEXT: [[TMP4:%.*]] = and i64 [[TMP2]], -71777214294589696358; CHECK-NEXT: [[OR27:%.*]] = or disjoint i64 [[TMP3]], [[TMP4]]359; CHECK-NEXT: ret i64 [[OR27]]360;361 %1 = lshr i64 %i, 8362 %shl = and i64 %1, 71776119061217280363 %2 = shl i64 %i, 8364 %shl3 = and i64 %2, -72057594037927936365 %or = or i64 %shl, %shl3366 %shl6 = and i64 %1, 1095216660480367 %or7 = or i64 %or, %shl6368 %shl10 = and i64 %2, 280375465082880369 %or11 = or i64 %or7, %shl10370 %shl14 = and i64 %1, 16711680371 %or15 = or i64 %or11, %shl14372 %shl18 = and i64 %2, 4278190080373 %or19 = or i64 %or15, %shl18374 %and21 = and i64 %1, 255375 %or23 = or i64 %or19, %and21376 %shl26 = and i64 %2, 65280377 %or27 = or i64 %or23, %shl26378 ret i64 %or27379}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, %b394 call void @use(i8 %and1)395 %and2 = and i8 %a, %d396 call void @use(i8 %and2)397 %or1 = or i8 %c, %and2398 call void @use(i8 %or1)399 %or2 = or i8 %or1, %and1400 ret i8 %or2401}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 canonicalization413 %and1 = and i8 %a, %b414 %and2 = and i8 %a, %d415 %or1 = or i8 %ct, %and2416 %or2 = or i8 %or1, %and1417 ret i8 %or2418}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 canonicalization430 %and1 = and i8 %a, %b431 %and2 = and i8 %d, %a432 %or1 = or i8 %ct, %and2433 %or2 = or i8 %or1, %and1434 ret i8 %or2435}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 canonicalization447 %and1 = and i8 %a, %b448 %and2 = and i8 %b, %d449 %or1 = or i8 %ct, %and2450 %or2 = or i8 %or1, %and1451 ret i8 %or2452}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 canonicalization464 %and1 = and i8 %a, %b465 %and2 = and i8 %d, %b466 %or1 = or i8 %ct, %and2467 %or2 = or i8 %or1, %and1468 ret i8 %or2469}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, %b480 %and2 = and i8 %a, %d481 %or1 = or i8 %and2, %c482 %or2 = or i8 %or1, %and1483 ret i8 %or2484}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, %b495 %and2 = and i8 %d, %a496 %or1 = or i8 %and2, %c497 %or2 = or i8 %or1, %and1498 ret i8 %or2499}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, %b510 %and2 = and i8 %b, %d511 %or1 = or i8 %and2, %c512 %or2 = or i8 %or1, %and1513 ret i8 %or2514}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, %b525 %and2 = and i8 %d, %b526 %or1 = or i8 %and2, %c527 %or2 = or i8 %or1, %and1528 ret i8 %or2529}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, %b544 call void @use(i8 %and1)545 %and2 = and i8 %a, %d546 call void @use(i8 %and2)547 %or1 = or i8 %c, %and2548 call void @use(i8 %or1)549 %or2 = or i8 %and1, %or1550 ret i8 %or2551}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 canonicalization563 %and1 = and i8 %a, %b564 %and2 = and i8 %a, %d565 %or1 = or i8 %ct, %and2566 %or2 = or i8 %and1, %or1567 ret i8 %or2568}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 canonicalization580 %and1 = and i8 %a, %b581 %and2 = and i8 %d, %a582 %or1 = or i8 %ct, %and2583 %or2 = or i8 %and1, %or1584 ret i8 %or2585}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 canonicalization597 %and1 = and i8 %a, %b598 %and2 = and i8 %b, %d599 %or1 = or i8 %ct, %and2600 %or2 = or i8 %and1, %or1601 ret i8 %or2602}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 canonicalization614 %and1 = and i8 %a, %b615 %and2 = and i8 %d, %b616 %or1 = or i8 %ct, %and2617 %or2 = or i8 %and1, %or1618 ret i8 %or2619}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, %b630 %and2 = and i8 %a, %d631 %or1 = or i8 %and2, %c632 %or2 = or i8 %and1, %or1633 ret i8 %or2634}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, %b645 %and2 = and i8 %d, %a646 %or1 = or i8 %and2, %c647 %or2 = or i8 %and1, %or1648 ret i8 %or2649}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, %b660 %and2 = and i8 %b, %d661 %or1 = or i8 %and2, %c662 %or2 = or i8 %and1, %or1663 ret i8 %or2664}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, %b675 %and2 = and i8 %d, %b676 %or1 = or i8 %and2, %c677 %or2 = or i8 %and1, %or1678 ret i8 %or2679}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:%.*]], 23686; CHECK-NEXT: [[AND:%.*]] = and i32 [[SHR]], 157687; CHECK-NEXT: call void @use2(i32 [[AND]])688; CHECK-NEXT: [[AND1:%.*]] = or i32 [[B:%.*]], 157689; CHECK-NEXT: [[OR:%.*]] = and i32 [[SHR]], [[AND1]]690; CHECK-NEXT: [[SHR8:%.*]] = lshr i32 [[B]], 23691; CHECK-NEXT: [[AND9:%.*]] = and i32 [[SHR8]], 157692; CHECK-NEXT: [[R:%.*]] = or i32 [[OR]], [[AND9]]693; CHECK-NEXT: ret i32 [[R]]694;695 %shr = ashr i32 %a, 23696 %conv = trunc i32 %shr to i8697 %conv1 = zext i8 %conv to i32698 %and = and i32 %conv1, 925699 call void @use2(i32 %and)700 %and3 = and i32 %shr, %b701 %or = or i32 %and3, %and702 %shr8 = ashr i32 %b, 23703 %and9 = and i32 %shr8, 157704 %r = or i32 %or, %and9705 ret i32 %r706}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]], true716; 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]], 0722; CHECK-NEXT: [[TMP9:%.*]] = insertvalue { i1, i1, i1, i1, i1 } [[TMP8]], i1 [[TMP4]], 1723; CHECK-NEXT: [[TMP10:%.*]] = insertvalue { i1, i1, i1, i1, i1 } [[TMP9]], i1 true, 2724; CHECK-NEXT: [[TMP11:%.*]] = insertvalue { i1, i1, i1, i1, i1 } [[TMP10]], i1 [[A_3]], 3725; CHECK-NEXT: [[TMP12:%.*]] = insertvalue { i1, i1, i1, i1, i1 } [[TMP11]], i1 [[DOTNOT1]], 4726; CHECK-NEXT: ret { i1, i1, i1, i1, i1 } [[TMP12]]727;728entry:729 %0 = and i1 %a_0, %b_0730 %1 = and i1 %a_3, %b_3731 %2 = xor i1 %a_2, %b_2732 %3 = and i1 %a_1, %b_1733 %4 = xor i1 %3, true734 %5 = and i1 %0, %a_1735 %6 = and i1 %2, %b_1736 %7 = or i1 %3, %6737 %d = or i1 %7, %5738 %8 = xor i1 %d, true739 %9 = xor i1 %8, true740 %10 = xor i1 %1, true741 %11 = and i1 %10, %4742 %12 = xor i1 %11, true743 %13 = insertvalue { i1, i1, i1, i1, i1 } zeroinitializer, i1 %9, 0744 %14 = insertvalue { i1, i1, i1, i1, i1 } %13, i1 %4, 1745 %15 = insertvalue { i1, i1, i1, i1, i1 } %14, i1 true, 2746 %16 = insertvalue { i1, i1, i1, i1, i1 } %15, i1 %a_3, 3747 %17 = insertvalue { i1, i1, i1, i1, i1 } %16, i1 %12, 4748 ret { i1, i1, i1, i1, i1 } %17749}750