282 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4; (A&B)^(A&C) -> A&(B^C) etc5 6define <4 x i32> @test_v4i32_xor_repeated_and_0(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) {7; CHECK-LABEL: @test_v4i32_xor_repeated_and_0(8; CHECK-NEXT: [[TMP1:%.*]] = xor <4 x i32> [[B:%.*]], [[C:%.*]]9; CHECK-NEXT: [[TMP2:%.*]] = and <4 x i32> [[A:%.*]], [[TMP1]]10; CHECK-NEXT: ret <4 x i32> [[TMP2]]11;12 %1 = and <4 x i32> %a, %b13 %2 = and <4 x i32> %a, %c14 %3 = xor <4 x i32> %1, %215 ret <4 x i32> %316}17 18define <4 x i32> @test_v4i32_xor_repeated_and_1(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) {19; CHECK-LABEL: @test_v4i32_xor_repeated_and_1(20; CHECK-NEXT: [[TMP1:%.*]] = xor <4 x i32> [[B:%.*]], [[C:%.*]]21; CHECK-NEXT: [[TMP2:%.*]] = and <4 x i32> [[A:%.*]], [[TMP1]]22; CHECK-NEXT: ret <4 x i32> [[TMP2]]23;24 %1 = and <4 x i32> %a, %b25 %2 = and <4 x i32> %c, %a26 %3 = xor <4 x i32> %1, %227 ret <4 x i32> %328}29 30; xor(bswap(a), c) to bswap(xor(a, bswap(c)))31 32declare <4 x i32> @llvm.bswap.v4i32(<4 x i32>)33 34define <4 x i32> @test_v4i32_xor_bswap_splatconst(<4 x i32> %a0) {35; CHECK-LABEL: @test_v4i32_xor_bswap_splatconst(36; CHECK-NEXT: [[TMP1:%.*]] = xor <4 x i32> [[A0:%.*]], splat (i32 -16777216)37; CHECK-NEXT: [[TMP2:%.*]] = call <4 x i32> @llvm.bswap.v4i32(<4 x i32> [[TMP1]])38; CHECK-NEXT: ret <4 x i32> [[TMP2]]39;40 %1 = call <4 x i32> @llvm.bswap.v4i32(<4 x i32> %a0)41 %2 = xor <4 x i32> %1, <i32 255, i32 255, i32 255, i32 255>42 ret <4 x i32> %243}44 45define <4 x i32> @test_v4i32_xor_bswap_const(<4 x i32> %a0) {46; CHECK-LABEL: @test_v4i32_xor_bswap_const(47; CHECK-NEXT: [[TMP1:%.*]] = call <4 x i32> @llvm.bswap.v4i32(<4 x i32> [[A0:%.*]])48; CHECK-NEXT: [[TMP2:%.*]] = xor <4 x i32> [[TMP1]], <i32 0, i32 -16777216, i32 2, i32 3>49; CHECK-NEXT: ret <4 x i32> [[TMP2]]50;51 %1 = call <4 x i32> @llvm.bswap.v4i32(<4 x i32> %a0)52 %2 = xor <4 x i32> %1, <i32 0, i32 -16777216, i32 2, i32 3>53 ret <4 x i32> %254}55 56define <4 x i32> @test_v4i32_xor_bswap_const_poison(<4 x i32> %a0) {57; CHECK-LABEL: @test_v4i32_xor_bswap_const_poison(58; CHECK-NEXT: [[TMP1:%.*]] = call <4 x i32> @llvm.bswap.v4i32(<4 x i32> [[A0:%.*]])59; CHECK-NEXT: [[TMP2:%.*]] = xor <4 x i32> [[TMP1]], <i32 poison, i32 0, i32 2, i32 3>60; CHECK-NEXT: ret <4 x i32> [[TMP2]]61;62 %1 = call <4 x i32> @llvm.bswap.v4i32(<4 x i32> %a0)63 %2 = xor <4 x i32> %1, <i32 poison, i32 0, i32 2, i32 3>64 ret <4 x i32> %265}66 67; DeMorgan's Law: ~(~X & Y) --> (X | ~Y)68 69define <4 x i32> @test_v4i32_demorgan_and(<4 x i32> %x, <4 x i32> %y) {70; CHECK-LABEL: @test_v4i32_demorgan_and(71; CHECK-NEXT: [[Y_NOT:%.*]] = xor <4 x i32> [[Y:%.*]], splat (i32 -1)72; CHECK-NEXT: [[TMP1:%.*]] = or <4 x i32> [[X:%.*]], [[Y_NOT]]73; CHECK-NEXT: ret <4 x i32> [[TMP1]]74;75 %1 = xor <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>, %x76 %2 = and <4 x i32> %1, %y77 %3 = xor <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>, %278 ret <4 x i32> %379}80 81; DeMorgan's Law: ~(~X | Y) --> (X & ~Y)82 83define <4 x i32> @test_v4i32_demorgan_or(<4 x i32> %x, <4 x i32> %y) {84; CHECK-LABEL: @test_v4i32_demorgan_or(85; CHECK-NEXT: [[Y_NOT:%.*]] = xor <4 x i32> [[Y:%.*]], splat (i32 -1)86; CHECK-NEXT: [[TMP1:%.*]] = and <4 x i32> [[X:%.*]], [[Y_NOT]]87; CHECK-NEXT: ret <4 x i32> [[TMP1]]88;89 %1 = xor <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>, %x90 %2 = or <4 x i32> %1, %y91 %3 = xor <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>, %292 ret <4 x i32> %393}94 95; ~(~X >>s Y) --> (X >>s Y)96 97define <4 x i32> @test_v4i32_not_ashr_not(<4 x i32> %x, <4 x i32> %y) {98; CHECK-LABEL: @test_v4i32_not_ashr_not(99; CHECK-NEXT: [[DOTNOT:%.*]] = ashr <4 x i32> [[X:%.*]], [[Y:%.*]]100; CHECK-NEXT: ret <4 x i32> [[DOTNOT]]101;102 %1 = xor <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>, %x103 %2 = ashr <4 x i32> %1, %y104 %3 = xor <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>, %2105 ret <4 x i32> %3106}107 108define <4 x i32> @test_v4i32_not_ashr_not_poison(<4 x i32> %x, <4 x i32> %y) {109; CHECK-LABEL: @test_v4i32_not_ashr_not_poison(110; CHECK-NEXT: [[DOTNOT:%.*]] = ashr <4 x i32> [[X:%.*]], [[Y:%.*]]111; CHECK-NEXT: ret <4 x i32> [[DOTNOT]]112;113 %1 = xor <4 x i32> <i32 -1, i32 -1, i32 -1, i32 poison>, %x114 %2 = ashr <4 x i32> %1, %y115 %3 = xor <4 x i32> <i32 -1, i32 -1, i32 poison, i32 -1>, %2116 ret <4 x i32> %3117}118 119; ~(C >>s Y) --> ~C >>u Y (when inverting the replicated sign bits)120 121define <4 x i32> @test_v4i32_not_ashr_negative_splatconst(<4 x i32> %a0) {122; CHECK-LABEL: @test_v4i32_not_ashr_negative_splatconst(123; CHECK-NEXT: [[TMP1:%.*]] = lshr <4 x i32> splat (i32 2), [[A0:%.*]]124; CHECK-NEXT: ret <4 x i32> [[TMP1]]125;126 %1 = ashr <4 x i32> <i32 -3, i32 -3, i32 -3, i32 -3>, %a0127 %2 = xor <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>, %1128 ret <4 x i32> %2129}130 131define <4 x i32> @test_v4i32_not_ashr_negative_const(<4 x i32> %a0) {132; CHECK-LABEL: @test_v4i32_not_ashr_negative_const(133; CHECK-NEXT: [[TMP1:%.*]] = lshr <4 x i32> <i32 2, i32 4, i32 6, i32 8>, [[A0:%.*]]134; CHECK-NEXT: ret <4 x i32> [[TMP1]]135;136 %1 = ashr <4 x i32> <i32 -3, i32 -5, i32 -7, i32 -9>, %a0137 %2 = xor <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>, %1138 ret <4 x i32> %2139}140 141define <4 x i32> @test_v4i32_not_ashr_negative_const_poison(<4 x i32> %a0) {142; CHECK-LABEL: @test_v4i32_not_ashr_negative_const_poison(143; CHECK-NEXT: [[TMP1:%.*]] = lshr <4 x i32> <i32 2, i32 4, i32 poison, i32 8>, [[A0:%.*]]144; CHECK-NEXT: ret <4 x i32> [[TMP1]]145;146 %1 = ashr <4 x i32> <i32 -3, i32 -5, i32 poison, i32 -9>, %a0147 %2 = xor <4 x i32> <i32 -1, i32 -1, i32 -1, i32 poison>, %1148 ret <4 x i32> %2149}150 151; ~(C >>u Y) --> ~C >>s Y (when inverting the replicated sign bits)152 153define <4 x i32> @test_v4i32_not_lshr_nonnegative_splatconst(<4 x i32> %a0) {154; CHECK-LABEL: @test_v4i32_not_lshr_nonnegative_splatconst(155; CHECK-NEXT: [[TMP1:%.*]] = ashr <4 x i32> splat (i32 -4), [[A0:%.*]]156; CHECK-NEXT: ret <4 x i32> [[TMP1]]157;158 %1 = lshr <4 x i32> <i32 3, i32 3, i32 3, i32 3>, %a0159 %2 = xor <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>, %1160 ret <4 x i32> %2161}162 163define <4 x i32> @test_v4i32_not_lshr_nonnegative_const(<4 x i32> %a0) {164; CHECK-LABEL: @test_v4i32_not_lshr_nonnegative_const(165; CHECK-NEXT: [[TMP1:%.*]] = ashr <4 x i32> <i32 -4, i32 -6, i32 -8, i32 -10>, [[A0:%.*]]166; CHECK-NEXT: ret <4 x i32> [[TMP1]]167;168 %1 = lshr <4 x i32> <i32 3, i32 5, i32 7, i32 9>, %a0169 %2 = xor <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>, %1170 ret <4 x i32> %2171}172 173define <4 x i32> @test_v4i32_not_lshr_nonnegative_const_poison(<4 x i32> %a0) {174; CHECK-LABEL: @test_v4i32_not_lshr_nonnegative_const_poison(175; CHECK-NEXT: [[TMP1:%.*]] = ashr <4 x i32> <i32 -4, i32 -6, i32 poison, i32 -10>, [[A0:%.*]]176; CHECK-NEXT: ret <4 x i32> [[TMP1]]177;178 %1 = lshr <4 x i32> <i32 3, i32 5, i32 poison, i32 9>, %a0179 %2 = xor <4 x i32> <i32 -1, i32 -1, i32 -1, i32 poison>, %1180 ret <4 x i32> %2181}182 183; ~(C-X) == X-C-1 == X+(-C-1)184 185define <4 x i32> @test_v4i32_not_sub_splatconst(<4 x i32> %a0) {186; CHECK-LABEL: @test_v4i32_not_sub_splatconst(187; CHECK-NEXT: [[TMP1:%.*]] = add <4 x i32> [[A0:%.*]], splat (i32 -4)188; CHECK-NEXT: ret <4 x i32> [[TMP1]]189;190 %1 = sub <4 x i32> <i32 3, i32 3, i32 3, i32 3>, %a0191 %2 = xor <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>, %1192 ret <4 x i32> %2193}194 195define <4 x i32> @test_v4i32_not_sub_const(<4 x i32> %a0) {196; CHECK-LABEL: @test_v4i32_not_sub_const(197; CHECK-NEXT: [[TMP1:%.*]] = add <4 x i32> [[A0:%.*]], <i32 -4, i32 -6, i32 0, i32 -16>198; CHECK-NEXT: ret <4 x i32> [[TMP1]]199;200 %1 = sub <4 x i32> <i32 3, i32 5, i32 -1, i32 15>, %a0201 %2 = xor <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>, %1202 ret <4 x i32> %2203}204 205define <4 x i32> @test_v4i32_not_sub_const_poison(<4 x i32> %a0) {206; CHECK-LABEL: @test_v4i32_not_sub_const_poison(207; CHECK-NEXT: [[TMP1:%.*]] = add <4 x i32> [[A0:%.*]], <i32 -4, i32 poison, i32 0, i32 -16>208; CHECK-NEXT: ret <4 x i32> [[TMP1]]209;210 %1 = sub <4 x i32> <i32 3, i32 poison, i32 -1, i32 15>, %a0211 %2 = xor <4 x i32> <i32 -1, i32 -1, i32 -1, i32 poison>, %1212 ret <4 x i32> %2213}214 215; (C - X) ^ signmask -> (C + signmask - X)216 217define <4 x i32> @test_v4i32_xor_signmask_sub_splatconst(<4 x i32> %a0) {218; CHECK-LABEL: @test_v4i32_xor_signmask_sub_splatconst(219; CHECK-NEXT: [[TMP1:%.*]] = sub <4 x i32> splat (i32 -2147483645), [[A0:%.*]]220; CHECK-NEXT: ret <4 x i32> [[TMP1]]221;222 %1 = sub <4 x i32> <i32 3, i32 3, i32 3, i32 3>, %a0223 %2 = xor <4 x i32> <i32 -2147483648, i32 -2147483648, i32 -2147483648, i32 -2147483648>, %1224 ret <4 x i32> %2225}226 227define <4 x i32> @test_v4i32_xor_signmask_sub_const(<4 x i32> %a0) {228; CHECK-LABEL: @test_v4i32_xor_signmask_sub_const(229; CHECK-NEXT: [[TMP1:%.*]] = sub <4 x i32> <i32 3, i32 5, i32 -1, i32 15>, [[A0:%.*]]230; CHECK-NEXT: [[TMP2:%.*]] = xor <4 x i32> [[TMP1]], splat (i32 -2147483648)231; CHECK-NEXT: ret <4 x i32> [[TMP2]]232;233 %1 = sub <4 x i32> <i32 3, i32 5, i32 -1, i32 15>, %a0234 %2 = xor <4 x i32> <i32 -2147483648, i32 -2147483648, i32 -2147483648, i32 -2147483648>, %1235 ret <4 x i32> %2236}237 238define <4 x i32> @test_v4i32_xor_signmask_sub_const_poison(<4 x i32> %a0) {239; CHECK-LABEL: @test_v4i32_xor_signmask_sub_const_poison(240; CHECK-NEXT: [[TMP1:%.*]] = sub <4 x i32> <i32 3, i32 poison, i32 -1, i32 15>, [[A0:%.*]]241; CHECK-NEXT: [[TMP2:%.*]] = xor <4 x i32> [[TMP1]], <i32 -2147483648, i32 -2147483648, i32 -2147483648, i32 poison>242; CHECK-NEXT: ret <4 x i32> [[TMP2]]243;244 %1 = sub <4 x i32> <i32 3, i32 poison, i32 -1, i32 15>, %a0245 %2 = xor <4 x i32> <i32 -2147483648, i32 -2147483648, i32 -2147483648, i32 poison>, %1246 ret <4 x i32> %2247}248 249; (X + C) ^ signmask -> (X + C + signmask)250 251define <4 x i32> @test_v4i32_xor_signmask_add_splatconst(<4 x i32> %a0) {252; CHECK-LABEL: @test_v4i32_xor_signmask_add_splatconst(253; CHECK-NEXT: [[TMP1:%.*]] = add <4 x i32> [[A0:%.*]], splat (i32 -2147483645)254; CHECK-NEXT: ret <4 x i32> [[TMP1]]255;256 %1 = add <4 x i32> <i32 3, i32 3, i32 3, i32 3>, %a0257 %2 = xor <4 x i32> <i32 -2147483648, i32 -2147483648, i32 -2147483648, i32 -2147483648>, %1258 ret <4 x i32> %2259}260 261define <4 x i32> @test_v4i32_xor_signmask_add_const(<4 x i32> %a0) {262; CHECK-LABEL: @test_v4i32_xor_signmask_add_const(263; CHECK-NEXT: [[TMP1:%.*]] = add <4 x i32> [[A0:%.*]], <i32 3, i32 5, i32 -1, i32 15>264; CHECK-NEXT: [[TMP2:%.*]] = xor <4 x i32> [[TMP1]], splat (i32 -2147483648)265; CHECK-NEXT: ret <4 x i32> [[TMP2]]266;267 %1 = add <4 x i32> <i32 3, i32 5, i32 -1, i32 15>, %a0268 %2 = xor <4 x i32> <i32 -2147483648, i32 -2147483648, i32 -2147483648, i32 -2147483648>, %1269 ret <4 x i32> %2270}271 272define <4 x i32> @test_v4i32_xor_signmask_add_const_poison(<4 x i32> %a0) {273; CHECK-LABEL: @test_v4i32_xor_signmask_add_const_poison(274; CHECK-NEXT: [[TMP1:%.*]] = add <4 x i32> [[A0:%.*]], <i32 3, i32 poison, i32 -1, i32 15>275; CHECK-NEXT: [[TMP2:%.*]] = xor <4 x i32> [[TMP1]], <i32 -2147483648, i32 -2147483648, i32 -2147483648, i32 poison>276; CHECK-NEXT: ret <4 x i32> [[TMP2]]277;278 %1 = add <4 x i32> <i32 3, i32 poison, i32 -1, i32 15>, %a0279 %2 = xor <4 x i32> <i32 -2147483648, i32 -2147483648, i32 -2147483648, i32 poison>, %1280 ret <4 x i32> %2281}282