brintos

brintos / llvm-project-archived public Read only

0
0
Text · 14.9 KiB · d78a9ee Raw
431 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4; https://bugs.llvm.org/show_bug.cgi?id=67735 6; Patterns:7;   (x & m) | (y & ~m)8;   (x & m) ^ (y & ~m)9;   (x & m) + (y & ~m)10; Should be transformed into:11;   (x & m) | (y & ~m)12; And then into:13;   ((x ^ y) & m) ^ y14 15; ============================================================================ ;16; Most basic positive tests17; ============================================================================ ;18 19define i32 @p(i32 %x, i32 %y, i32 noundef %m) {20; CHECK-LABEL: @p(21; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], [[M:%.*]]22; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M]], -123; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[Y:%.*]], [[NEG]]24; CHECK-NEXT:    [[RET:%.*]] = or disjoint i32 [[AND]], [[AND1]]25; CHECK-NEXT:    ret i32 [[RET]]26;27  %and = and i32 %x, %m28  %neg = xor i32 %m, -129  %and1 = and i32 %neg, %y30  %ret = add i32 %and, %and131  ret i32 %ret32}33 34define <2 x i32> @p_splatvec(<2 x i32> %x, <2 x i32> %y, <2 x i32> noundef %m) {35; CHECK-LABEL: @p_splatvec(36; CHECK-NEXT:    [[AND:%.*]] = and <2 x i32> [[X:%.*]], [[M:%.*]]37; CHECK-NEXT:    [[NEG:%.*]] = xor <2 x i32> [[M]], splat (i32 -1)38; CHECK-NEXT:    [[AND1:%.*]] = and <2 x i32> [[Y:%.*]], [[NEG]]39; CHECK-NEXT:    [[RET:%.*]] = or disjoint <2 x i32> [[AND]], [[AND1]]40; CHECK-NEXT:    ret <2 x i32> [[RET]]41;42  %and = and <2 x i32> %x, %m43  %neg = xor <2 x i32> %m, <i32 -1, i32 -1>44  %and1 = and <2 x i32> %neg, %y45  %ret = add <2 x i32> %and, %and146  ret <2 x i32> %ret47}48 49define <3 x i32> @p_vec_undef(<3 x i32> %x, <3 x i32> %y, <3 x i32> noundef %m) {50; CHECK-LABEL: @p_vec_undef(51; CHECK-NEXT:    [[AND:%.*]] = and <3 x i32> [[X:%.*]], [[M:%.*]]52; CHECK-NEXT:    [[NEG:%.*]] = xor <3 x i32> [[M]], <i32 -1, i32 undef, i32 -1>53; CHECK-NEXT:    [[AND1:%.*]] = and <3 x i32> [[NEG]], [[Y:%.*]]54; CHECK-NEXT:    [[RET:%.*]] = add <3 x i32> [[AND]], [[AND1]]55; CHECK-NEXT:    ret <3 x i32> [[RET]]56;57  %and = and <3 x i32> %x, %m58  %neg = xor <3 x i32> %m, <i32 -1, i32 undef, i32 -1>59  %and1 = and <3 x i32> %neg, %y60  %ret = add <3 x i32> %and, %and161  ret <3 x i32> %ret62}63 64define <3 x i32> @p_vec_poison(<3 x i32> %x, <3 x i32> %y, <3 x i32> noundef %m) {65; CHECK-LABEL: @p_vec_poison(66; CHECK-NEXT:    [[AND:%.*]] = and <3 x i32> [[X:%.*]], [[M:%.*]]67; CHECK-NEXT:    [[NEG:%.*]] = xor <3 x i32> [[M]], <i32 -1, i32 poison, i32 -1>68; CHECK-NEXT:    [[AND1:%.*]] = and <3 x i32> [[Y:%.*]], [[NEG]]69; CHECK-NEXT:    [[RET:%.*]] = or disjoint <3 x i32> [[AND]], [[AND1]]70; CHECK-NEXT:    ret <3 x i32> [[RET]]71;72  %and = and <3 x i32> %x, %m73  %neg = xor <3 x i32> %m, <i32 -1, i32 poison, i32 -1>74  %and1 = and <3 x i32> %neg, %y75  %ret = add <3 x i32> %and, %and176  ret <3 x i32> %ret77}78 79; ============================================================================ ;80; Constant mask.81; ============================================================================ ;82 83define i32 @p_constmask(i32 %x, i32 %y) {84; CHECK-LABEL: @p_constmask(85; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 6528086; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[Y:%.*]], -6528187; CHECK-NEXT:    [[RET:%.*]] = or disjoint i32 [[AND]], [[AND1]]88; CHECK-NEXT:    ret i32 [[RET]]89;90  %and = and i32 %x, 6528091  %and1 = and i32 %y, -6528192  %ret = add i32 %and, %and193  ret i32 %ret94}95 96define <2 x i32> @p_constmask_splatvec(<2 x i32> %x, <2 x i32> %y) {97; CHECK-LABEL: @p_constmask_splatvec(98; CHECK-NEXT:    [[AND:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 65280)99; CHECK-NEXT:    [[AND1:%.*]] = and <2 x i32> [[Y:%.*]], splat (i32 -65281)100; CHECK-NEXT:    [[RET:%.*]] = or disjoint <2 x i32> [[AND]], [[AND1]]101; CHECK-NEXT:    ret <2 x i32> [[RET]]102;103  %and = and <2 x i32> %x, <i32 65280, i32 65280>104  %and1 = and <2 x i32> %y, <i32 -65281, i32 -65281>105  %ret = add <2 x i32> %and, %and1106  ret <2 x i32> %ret107}108 109define <2 x i32> @p_constmask_vec(<2 x i32> %x, <2 x i32> %y) {110; CHECK-LABEL: @p_constmask_vec(111; CHECK-NEXT:    [[AND:%.*]] = and <2 x i32> [[X:%.*]], <i32 65280, i32 16776960>112; CHECK-NEXT:    [[AND1:%.*]] = and <2 x i32> [[Y:%.*]], <i32 -65281, i32 -16776961>113; CHECK-NEXT:    [[RET:%.*]] = add <2 x i32> [[AND]], [[AND1]]114; CHECK-NEXT:    ret <2 x i32> [[RET]]115;116  %and = and <2 x i32> %x, <i32 65280, i32 16776960>117  %and1 = and <2 x i32> %y, <i32 -65281, i32 -16776961>118  %ret = add <2 x i32> %and, %and1119  ret <2 x i32> %ret120}121 122define <3 x i32> @p_constmask_vec_undef(<3 x i32> %x, <3 x i32> %y) {123; CHECK-LABEL: @p_constmask_vec_undef(124; CHECK-NEXT:    [[AND:%.*]] = and <3 x i32> [[X:%.*]], <i32 65280, i32 undef, i32 65280>125; CHECK-NEXT:    [[AND1:%.*]] = and <3 x i32> [[Y:%.*]], <i32 -65281, i32 undef, i32 -65281>126; CHECK-NEXT:    [[RET:%.*]] = add <3 x i32> [[AND]], [[AND1]]127; CHECK-NEXT:    ret <3 x i32> [[RET]]128;129  %and = and <3 x i32> %x, <i32 65280, i32 undef, i32 65280>130  %and1 = and <3 x i32> %y, <i32 -65281, i32 undef, i32 -65281>131  %ret = add <3 x i32> %and, %and1132  ret <3 x i32> %ret133}134 135; ============================================================================ ;136; Constant mask with no common bits set, but common unset bits.137; ============================================================================ ;138 139define i32 @p_constmask2(i32 %x, i32 %y) {140; CHECK-LABEL: @p_constmask2(141; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 61440142; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[Y:%.*]], -65281143; CHECK-NEXT:    [[RET:%.*]] = or disjoint i32 [[AND]], [[AND1]]144; CHECK-NEXT:    ret i32 [[RET]]145;146  %and = and i32 %x, 61440147  %and1 = and i32 %y, -65281148  %ret = add i32 %and, %and1149  ret i32 %ret150}151 152define <2 x i32> @p_constmask2_splatvec(<2 x i32> %x, <2 x i32> %y) {153; CHECK-LABEL: @p_constmask2_splatvec(154; CHECK-NEXT:    [[AND:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 61440)155; CHECK-NEXT:    [[AND1:%.*]] = and <2 x i32> [[Y:%.*]], splat (i32 -65281)156; CHECK-NEXT:    [[RET:%.*]] = or disjoint <2 x i32> [[AND]], [[AND1]]157; CHECK-NEXT:    ret <2 x i32> [[RET]]158;159  %and = and <2 x i32> %x, <i32 61440, i32 61440>160  %and1 = and <2 x i32> %y, <i32 -65281, i32 -65281>161  %ret = add <2 x i32> %and, %and1162  ret <2 x i32> %ret163}164 165define <2 x i32> @p_constmask2_vec(<2 x i32> %x, <2 x i32> %y) {166; CHECK-LABEL: @p_constmask2_vec(167; CHECK-NEXT:    [[AND:%.*]] = and <2 x i32> [[X:%.*]], <i32 61440, i32 16711680>168; CHECK-NEXT:    [[AND1:%.*]] = and <2 x i32> [[Y:%.*]], <i32 -65281, i32 -16776961>169; CHECK-NEXT:    [[RET:%.*]] = add <2 x i32> [[AND]], [[AND1]]170; CHECK-NEXT:    ret <2 x i32> [[RET]]171;172  %and = and <2 x i32> %x, <i32 61440, i32 16711680>173  %and1 = and <2 x i32> %y, <i32 -65281, i32 -16776961>174  %ret = add <2 x i32> %and, %and1175  ret <2 x i32> %ret176}177 178define <3 x i32> @p_constmask2_vec_undef(<3 x i32> %x, <3 x i32> %y) {179; CHECK-LABEL: @p_constmask2_vec_undef(180; CHECK-NEXT:    [[AND:%.*]] = and <3 x i32> [[X:%.*]], <i32 61440, i32 undef, i32 61440>181; CHECK-NEXT:    [[AND1:%.*]] = and <3 x i32> [[Y:%.*]], <i32 -65281, i32 undef, i32 -65281>182; CHECK-NEXT:    [[RET:%.*]] = add <3 x i32> [[AND]], [[AND1]]183; CHECK-NEXT:    ret <3 x i32> [[RET]]184;185  %and = and <3 x i32> %x, <i32 61440, i32 undef, i32 61440>186  %and1 = and <3 x i32> %y, <i32 -65281, i32 undef, i32 -65281>187  %ret = add <3 x i32> %and, %and1188  ret <3 x i32> %ret189}190 191; ============================================================================ ;192; Commutativity.193; ============================================================================ ;194 195; Used to make sure that the IR complexity sorting does not interfere.196declare i32 @gen32()197 198define i32 @p_commutative0(i32 %x, i32 %y, i32 noundef %m) {199; CHECK-LABEL: @p_commutative0(200; CHECK-NEXT:    [[AND:%.*]] = and i32 [[M:%.*]], [[X:%.*]]201; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M]], -1202; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[Y:%.*]], [[NEG]]203; CHECK-NEXT:    [[RET:%.*]] = or disjoint i32 [[AND]], [[AND1]]204; CHECK-NEXT:    ret i32 [[RET]]205;206  %and = and i32 %m, %x ; swapped order207  %neg = xor i32 %m, -1208  %and1 = and i32 %neg, %y209  %ret = add i32 %and, %and1210  ret i32 %ret211}212 213define i32 @p_commutative1(i32 %x, i32 noundef %m) {214; CHECK-LABEL: @p_commutative1(215; CHECK-NEXT:    [[Y:%.*]] = call i32 @gen32()216; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], [[M:%.*]]217; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M]], -1218; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[Y]], [[NEG]]219; CHECK-NEXT:    [[RET:%.*]] = or disjoint i32 [[AND]], [[AND1]]220; CHECK-NEXT:    ret i32 [[RET]]221;222  %y = call i32 @gen32()223  %and = and i32 %x, %m224  %neg = xor i32 %m, -1225  %and1 = and i32 %y, %neg; swapped order226  %ret = add i32 %and, %and1227  ret i32 %ret228}229 230define i32 @p_commutative2(i32 %x, i32 %y, i32 noundef %m) {231; CHECK-LABEL: @p_commutative2(232; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], [[M:%.*]]233; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M]], -1234; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[Y:%.*]], [[NEG]]235; CHECK-NEXT:    [[RET:%.*]] = or disjoint i32 [[AND1]], [[AND]]236; CHECK-NEXT:    ret i32 [[RET]]237;238  %and = and i32 %x, %m239  %neg = xor i32 %m, -1240  %and1 = and i32 %neg, %y241  %ret = add i32 %and1, %and ; swapped order242  ret i32 %ret243}244 245define i32 @p_commutative3(i32 %x, i32 noundef %m) {246; CHECK-LABEL: @p_commutative3(247; CHECK-NEXT:    [[Y:%.*]] = call i32 @gen32()248; CHECK-NEXT:    [[AND:%.*]] = and i32 [[M:%.*]], [[X:%.*]]249; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M]], -1250; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[Y]], [[NEG]]251; CHECK-NEXT:    [[RET:%.*]] = or disjoint i32 [[AND]], [[AND1]]252; CHECK-NEXT:    ret i32 [[RET]]253;254  %y = call i32 @gen32()255  %and = and i32 %m, %x ; swapped order256  %neg = xor i32 %m, -1257  %and1 = and i32 %y, %neg; swapped order258  %ret = add i32 %and, %and1259  ret i32 %ret260}261 262define i32 @p_commutative4(i32 %x, i32 %y, i32 noundef %m) {263; CHECK-LABEL: @p_commutative4(264; CHECK-NEXT:    [[AND:%.*]] = and i32 [[M:%.*]], [[X:%.*]]265; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M]], -1266; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[Y:%.*]], [[NEG]]267; CHECK-NEXT:    [[RET:%.*]] = or disjoint i32 [[AND1]], [[AND]]268; CHECK-NEXT:    ret i32 [[RET]]269;270  %and = and i32 %m, %x ; swapped order271  %neg = xor i32 %m, -1272  %and1 = and i32 %neg, %y273  %ret = add i32 %and1, %and ; swapped order274  ret i32 %ret275}276 277define i32 @p_commutative5(i32 %x, i32 noundef %m) {278; CHECK-LABEL: @p_commutative5(279; CHECK-NEXT:    [[Y:%.*]] = call i32 @gen32()280; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], [[M:%.*]]281; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M]], -1282; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[Y]], [[NEG]]283; CHECK-NEXT:    [[RET:%.*]] = or disjoint i32 [[AND1]], [[AND]]284; CHECK-NEXT:    ret i32 [[RET]]285;286  %y = call i32 @gen32()287  %and = and i32 %x, %m288  %neg = xor i32 %m, -1289  %and1 = and i32 %y, %neg; swapped order290  %ret = add i32 %and1, %and ; swapped order291  ret i32 %ret292}293 294define i32 @p_commutative6(i32 %x, i32 noundef %m) {295; CHECK-LABEL: @p_commutative6(296; CHECK-NEXT:    [[Y:%.*]] = call i32 @gen32()297; CHECK-NEXT:    [[AND:%.*]] = and i32 [[M:%.*]], [[X:%.*]]298; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M]], -1299; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[Y]], [[NEG]]300; CHECK-NEXT:    [[RET:%.*]] = or disjoint i32 [[AND1]], [[AND]]301; CHECK-NEXT:    ret i32 [[RET]]302;303  %y = call i32 @gen32()304  %and = and i32 %m, %x ; swapped order305  %neg = xor i32 %m, -1306  %and1 = and i32 %y, %neg; swapped order307  %ret = add i32 %and1, %and ; swapped order308  ret i32 %ret309}310 311define i32 @p_constmask_commutative(i32 %x, i32 %y) {312; CHECK-LABEL: @p_constmask_commutative(313; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 65280314; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[Y:%.*]], -65281315; CHECK-NEXT:    [[RET:%.*]] = or disjoint i32 [[AND1]], [[AND]]316; CHECK-NEXT:    ret i32 [[RET]]317;318  %and = and i32 %x, 65280319  %and1 = and i32 %y, -65281320  %ret = add i32 %and1, %and ; swapped order321  ret i32 %ret322}323 324; ============================================================================ ;325; Negative tests. Should not be folded.326; ============================================================================ ;327 328; One use only.329 330declare void @use32(i32)331 332define i32 @n0_oneuse(i32 %x, i32 %y, i32 noundef %m) {333; CHECK-LABEL: @n0_oneuse(334; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], [[M:%.*]]335; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M]], -1336; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[Y:%.*]], [[NEG]]337; CHECK-NEXT:    [[RET:%.*]] = or disjoint i32 [[AND]], [[AND1]]338; CHECK-NEXT:    call void @use32(i32 [[AND]])339; CHECK-NEXT:    call void @use32(i32 [[NEG]])340; CHECK-NEXT:    call void @use32(i32 [[AND1]])341; CHECK-NEXT:    ret i32 [[RET]]342;343  %and = and i32 %x, %m344  %neg = xor i32 %m, -1345  %and1 = and i32 %neg, %y346  %ret = add i32 %and, %and1347  call void @use32(i32 %and)348  call void @use32(i32 %neg)349  call void @use32(i32 %and1)350  ret i32 %ret351}352 353define i32 @n0_constmask_oneuse(i32 %x, i32 %y) {354; CHECK-LABEL: @n0_constmask_oneuse(355; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 65280356; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[Y:%.*]], -65281357; CHECK-NEXT:    [[RET:%.*]] = or disjoint i32 [[AND]], [[AND1]]358; CHECK-NEXT:    call void @use32(i32 [[AND]])359; CHECK-NEXT:    call void @use32(i32 [[AND1]])360; CHECK-NEXT:    ret i32 [[RET]]361;362  %and = and i32 %x, 65280363  %and1 = and i32 %y, -65281364  %ret = add i32 %and, %and1365  call void @use32(i32 %and)366  call void @use32(i32 %and1)367  ret i32 %ret368}369 370; Bad xor constant371 372define i32 @n1_badxor(i32 %x, i32 %y, i32 %m) {373; CHECK-LABEL: @n1_badxor(374; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], [[M:%.*]]375; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M]], 1376; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[NEG]], [[Y:%.*]]377; CHECK-NEXT:    [[RET:%.*]] = add i32 [[AND]], [[AND1]]378; CHECK-NEXT:    ret i32 [[RET]]379;380  %and = and i32 %x, %m381  %neg = xor i32 %m, 1 ; not -1382  %and1 = and i32 %neg, %y383  %ret = add i32 %and, %and1384  ret i32 %ret385}386 387; Different mask is used388 389define i32 @n2_badmask(i32 %x, i32 %y, i32 %m1, i32 %m2) {390; CHECK-LABEL: @n2_badmask(391; CHECK-NEXT:    [[AND:%.*]] = and i32 [[M1:%.*]], [[X:%.*]]392; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[M2:%.*]], -1393; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[Y:%.*]], [[NEG]]394; CHECK-NEXT:    [[RET:%.*]] = add i32 [[AND]], [[AND1]]395; CHECK-NEXT:    ret i32 [[RET]]396;397  %and = and i32 %m1, %x398  %neg = xor i32 %m2, -1 ; different mask, not %m1399  %and1 = and i32 %neg, %y400  %ret = add i32 %and, %and1401  ret i32 %ret402}403 404; Different const mask is used405 406define i32 @n3_constmask_badmask(i32 %x, i32 %y) {407; CHECK-LABEL: @n3_constmask_badmask(408; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 65280409; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[Y:%.*]], -65280410; CHECK-NEXT:    [[RET:%.*]] = add i32 [[AND]], [[AND1]]411; CHECK-NEXT:    ret i32 [[RET]]412;413  %and = and i32 %x, 65280414  %and1 = and i32 %y, -65280 ; not -65281, so they have one common bit set415  %ret = add i32 %and, %and1416  ret i32 %ret417}418 419define i32 @n3_constmask_samemask(i32 %x, i32 %y) {420; CHECK-LABEL: @n3_constmask_samemask(421; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 65280422; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[Y:%.*]], 65280423; CHECK-NEXT:    [[RET:%.*]] = add nuw nsw i32 [[AND]], [[AND1]]424; CHECK-NEXT:    ret i32 [[RET]]425;426  %and = and i32 %x, 65280427  %and1 = and i32 %y, 65280 ; both masks are the same428  %ret = add i32 %and, %and1429  ret i32 %ret430}431