644 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=arm64-none-linux-gnu < %s | FileCheck %s --check-prefixes=CHECK,CHECK-SD3; RUN: llc -mtriple=arm64-none-linux-gnu -global-isel < %s | FileCheck %s --check-prefixes=CHECK,CHECK-GI4 5declare <8 x i8> @llvm.aarch64.neon.uabd.v8i8(<8 x i8>, <8 x i8>)6declare <8 x i8> @llvm.aarch64.neon.sabd.v8i8(<8 x i8>, <8 x i8>)7 8define <8 x i8> @test_uabd_v8i8(<8 x i8> %lhs, <8 x i8> %rhs) {9; CHECK-LABEL: test_uabd_v8i8:10; CHECK: // %bb.0:11; CHECK-NEXT: uabd v0.8b, v0.8b, v1.8b12; CHECK-NEXT: ret13 %abd = call <8 x i8> @llvm.aarch64.neon.uabd.v8i8(<8 x i8> %lhs, <8 x i8> %rhs)14 ret <8 x i8> %abd15}16 17define <8 x i8> @test_uaba_v8i8(<8 x i8> %lhs, <8 x i8> %rhs) {18; CHECK-LABEL: test_uaba_v8i8:19; CHECK: // %bb.0:20; CHECK-NEXT: uaba v0.8b, v0.8b, v1.8b21; CHECK-NEXT: ret22 %abd = call <8 x i8> @llvm.aarch64.neon.uabd.v8i8(<8 x i8> %lhs, <8 x i8> %rhs)23 %aba = add <8 x i8> %lhs, %abd24 ret <8 x i8> %aba25}26 27define <8 x i8> @test_sabd_v8i8(<8 x i8> %lhs, <8 x i8> %rhs) {28; CHECK-LABEL: test_sabd_v8i8:29; CHECK: // %bb.0:30; CHECK-NEXT: sabd v0.8b, v0.8b, v1.8b31; CHECK-NEXT: ret32 %abd = call <8 x i8> @llvm.aarch64.neon.sabd.v8i8(<8 x i8> %lhs, <8 x i8> %rhs)33 ret <8 x i8> %abd34}35 36define <8 x i8> @test_saba_v8i8(<8 x i8> %lhs, <8 x i8> %rhs) {37; CHECK-LABEL: test_saba_v8i8:38; CHECK: // %bb.0:39; CHECK-NEXT: saba v0.8b, v0.8b, v1.8b40; CHECK-NEXT: ret41 %abd = call <8 x i8> @llvm.aarch64.neon.sabd.v8i8(<8 x i8> %lhs, <8 x i8> %rhs)42 %aba = add <8 x i8> %lhs, %abd43 ret <8 x i8> %aba44}45 46declare <16 x i8> @llvm.aarch64.neon.uabd.v16i8(<16 x i8>, <16 x i8>)47declare <16 x i8> @llvm.aarch64.neon.sabd.v16i8(<16 x i8>, <16 x i8>)48 49define <16 x i8> @test_uabd_v16i8(<16 x i8> %lhs, <16 x i8> %rhs) {50; CHECK-LABEL: test_uabd_v16i8:51; CHECK: // %bb.0:52; CHECK-NEXT: uabd v0.16b, v0.16b, v1.16b53; CHECK-NEXT: ret54 %abd = call <16 x i8> @llvm.aarch64.neon.uabd.v16i8(<16 x i8> %lhs, <16 x i8> %rhs)55 ret <16 x i8> %abd56}57 58define <16 x i8> @test_uaba_v16i8(<16 x i8> %lhs, <16 x i8> %rhs) {59; CHECK-LABEL: test_uaba_v16i8:60; CHECK: // %bb.0:61; CHECK-NEXT: uaba v0.16b, v0.16b, v1.16b62; CHECK-NEXT: ret63 %abd = call <16 x i8> @llvm.aarch64.neon.uabd.v16i8(<16 x i8> %lhs, <16 x i8> %rhs)64 %aba = add <16 x i8> %lhs, %abd65 ret <16 x i8> %aba66}67 68define <16 x i8> @test_sabd_v16i8(<16 x i8> %lhs, <16 x i8> %rhs) {69; CHECK-LABEL: test_sabd_v16i8:70; CHECK: // %bb.0:71; CHECK-NEXT: sabd v0.16b, v0.16b, v1.16b72; CHECK-NEXT: ret73 %abd = call <16 x i8> @llvm.aarch64.neon.sabd.v16i8(<16 x i8> %lhs, <16 x i8> %rhs)74 ret <16 x i8> %abd75}76 77define <16 x i8> @test_saba_v16i8(<16 x i8> %lhs, <16 x i8> %rhs) {78; CHECK-LABEL: test_saba_v16i8:79; CHECK: // %bb.0:80; CHECK-NEXT: saba v0.16b, v0.16b, v1.16b81; CHECK-NEXT: ret82 %abd = call <16 x i8> @llvm.aarch64.neon.sabd.v16i8(<16 x i8> %lhs, <16 x i8> %rhs)83 %aba = add <16 x i8> %lhs, %abd84 ret <16 x i8> %aba85}86 87declare <4 x i16> @llvm.aarch64.neon.uabd.v4i16(<4 x i16>, <4 x i16>)88declare <4 x i16> @llvm.aarch64.neon.sabd.v4i16(<4 x i16>, <4 x i16>)89 90define <4 x i16> @test_uabd_v4i16(<4 x i16> %lhs, <4 x i16> %rhs) {91; CHECK-LABEL: test_uabd_v4i16:92; CHECK: // %bb.0:93; CHECK-NEXT: uabd v0.4h, v0.4h, v1.4h94; CHECK-NEXT: ret95 %abd = call <4 x i16> @llvm.aarch64.neon.uabd.v4i16(<4 x i16> %lhs, <4 x i16> %rhs)96 ret <4 x i16> %abd97}98 99define <4 x i16> @test_uaba_v4i16(<4 x i16> %lhs, <4 x i16> %rhs) {100; CHECK-LABEL: test_uaba_v4i16:101; CHECK: // %bb.0:102; CHECK-NEXT: uaba v0.4h, v0.4h, v1.4h103; CHECK-NEXT: ret104 %abd = call <4 x i16> @llvm.aarch64.neon.uabd.v4i16(<4 x i16> %lhs, <4 x i16> %rhs)105 %aba = add <4 x i16> %lhs, %abd106 ret <4 x i16> %aba107}108 109define <4 x i16> @test_sabd_v4i16(<4 x i16> %lhs, <4 x i16> %rhs) {110; CHECK-LABEL: test_sabd_v4i16:111; CHECK: // %bb.0:112; CHECK-NEXT: sabd v0.4h, v0.4h, v1.4h113; CHECK-NEXT: ret114 %abd = call <4 x i16> @llvm.aarch64.neon.sabd.v4i16(<4 x i16> %lhs, <4 x i16> %rhs)115 ret <4 x i16> %abd116}117 118define <4 x i16> @test_saba_v4i16(<4 x i16> %lhs, <4 x i16> %rhs) {119; CHECK-LABEL: test_saba_v4i16:120; CHECK: // %bb.0:121; CHECK-NEXT: saba v0.4h, v0.4h, v1.4h122; CHECK-NEXT: ret123 %abd = call <4 x i16> @llvm.aarch64.neon.sabd.v4i16(<4 x i16> %lhs, <4 x i16> %rhs)124 %aba = add <4 x i16> %lhs, %abd125 ret <4 x i16> %aba126}127 128declare <8 x i16> @llvm.aarch64.neon.uabd.v8i16(<8 x i16>, <8 x i16>)129declare <8 x i16> @llvm.aarch64.neon.sabd.v8i16(<8 x i16>, <8 x i16>)130 131define <8 x i16> @test_uabd_v8i16(<8 x i16> %lhs, <8 x i16> %rhs) {132; CHECK-LABEL: test_uabd_v8i16:133; CHECK: // %bb.0:134; CHECK-NEXT: uabd v0.8h, v0.8h, v1.8h135; CHECK-NEXT: ret136 %abd = call <8 x i16> @llvm.aarch64.neon.uabd.v8i16(<8 x i16> %lhs, <8 x i16> %rhs)137 ret <8 x i16> %abd138}139 140define <8 x i16> @test_uaba_v8i16(<8 x i16> %lhs, <8 x i16> %rhs) {141; CHECK-LABEL: test_uaba_v8i16:142; CHECK: // %bb.0:143; CHECK-NEXT: uaba v0.8h, v0.8h, v1.8h144; CHECK-NEXT: ret145 %abd = call <8 x i16> @llvm.aarch64.neon.uabd.v8i16(<8 x i16> %lhs, <8 x i16> %rhs)146 %aba = add <8 x i16> %lhs, %abd147 ret <8 x i16> %aba148}149 150define <8 x i16> @test_sabd_v8i16(<8 x i16> %lhs, <8 x i16> %rhs) {151; CHECK-LABEL: test_sabd_v8i16:152; CHECK: // %bb.0:153; CHECK-NEXT: sabd v0.8h, v0.8h, v1.8h154; CHECK-NEXT: ret155 %abd = call <8 x i16> @llvm.aarch64.neon.sabd.v8i16(<8 x i16> %lhs, <8 x i16> %rhs)156 ret <8 x i16> %abd157}158 159define <8 x i16> @test_saba_v8i16(<8 x i16> %lhs, <8 x i16> %rhs) {160; CHECK-LABEL: test_saba_v8i16:161; CHECK: // %bb.0:162; CHECK-NEXT: saba v0.8h, v0.8h, v1.8h163; CHECK-NEXT: ret164 %abd = call <8 x i16> @llvm.aarch64.neon.sabd.v8i16(<8 x i16> %lhs, <8 x i16> %rhs)165 %aba = add <8 x i16> %lhs, %abd166 ret <8 x i16> %aba167}168 169declare <2 x i32> @llvm.aarch64.neon.uabd.v2i32(<2 x i32>, <2 x i32>)170declare <2 x i32> @llvm.aarch64.neon.sabd.v2i32(<2 x i32>, <2 x i32>)171 172define <2 x i32> @test_uabd_v2i32(<2 x i32> %lhs, <2 x i32> %rhs) {173; CHECK-LABEL: test_uabd_v2i32:174; CHECK: // %bb.0:175; CHECK-NEXT: uabd v0.2s, v0.2s, v1.2s176; CHECK-NEXT: ret177 %abd = call <2 x i32> @llvm.aarch64.neon.uabd.v2i32(<2 x i32> %lhs, <2 x i32> %rhs)178 ret <2 x i32> %abd179}180 181define <2 x i32> @test_uaba_v2i32(<2 x i32> %lhs, <2 x i32> %rhs) {182; CHECK-LABEL: test_uaba_v2i32:183; CHECK: // %bb.0:184; CHECK-NEXT: uaba v0.2s, v0.2s, v1.2s185; CHECK-NEXT: ret186 %abd = call <2 x i32> @llvm.aarch64.neon.uabd.v2i32(<2 x i32> %lhs, <2 x i32> %rhs)187 %aba = add <2 x i32> %lhs, %abd188 ret <2 x i32> %aba189}190 191define <2 x i32> @test_sabd_v2i32(<2 x i32> %lhs, <2 x i32> %rhs) {192; CHECK-LABEL: test_sabd_v2i32:193; CHECK: // %bb.0:194; CHECK-NEXT: sabd v0.2s, v0.2s, v1.2s195; CHECK-NEXT: ret196 %abd = call <2 x i32> @llvm.aarch64.neon.sabd.v2i32(<2 x i32> %lhs, <2 x i32> %rhs)197 ret <2 x i32> %abd198}199 200define <2 x i32> @test_sabd_v2i32_const() {201; CHECK-SD-LABEL: test_sabd_v2i32_const:202; CHECK-SD: // %bb.0:203; CHECK-SD-NEXT: adrp x8, .LCPI19_0204; CHECK-SD-NEXT: ldr d0, [x8, :lo12:.LCPI19_0]205; CHECK-SD-NEXT: ret206;207; CHECK-GI-LABEL: test_sabd_v2i32_const:208; CHECK-GI: // %bb.0:209; CHECK-GI-NEXT: adrp x8, .LCPI19_1210; CHECK-GI-NEXT: adrp x9, .LCPI19_0211; CHECK-GI-NEXT: ldr d0, [x8, :lo12:.LCPI19_1]212; CHECK-GI-NEXT: ldr d1, [x9, :lo12:.LCPI19_0]213; CHECK-GI-NEXT: sabd v0.2s, v0.2s, v1.2s214; CHECK-GI-NEXT: ret215 %1 = tail call <2 x i32> @llvm.aarch64.neon.sabd.v2i32(216 <2 x i32> <i32 -2147483648, i32 2147450880>,217 <2 x i32> <i32 -65536, i32 65535>)218 ret <2 x i32> %1219}220 221define <2 x i32> @test_saba_v2i32(<2 x i32> %lhs, <2 x i32> %rhs) {222; CHECK-LABEL: test_saba_v2i32:223; CHECK: // %bb.0:224; CHECK-NEXT: saba v0.2s, v0.2s, v1.2s225; CHECK-NEXT: ret226 %abd = call <2 x i32> @llvm.aarch64.neon.sabd.v2i32(<2 x i32> %lhs, <2 x i32> %rhs)227 %aba = add <2 x i32> %lhs, %abd228 ret <2 x i32> %aba229}230 231declare <4 x i32> @llvm.aarch64.neon.uabd.v4i32(<4 x i32>, <4 x i32>)232declare <4 x i32> @llvm.aarch64.neon.sabd.v4i32(<4 x i32>, <4 x i32>)233 234define <4 x i32> @test_uabd_v4i32(<4 x i32> %lhs, <4 x i32> %rhs) {235; CHECK-LABEL: test_uabd_v4i32:236; CHECK: // %bb.0:237; CHECK-NEXT: uabd v0.4s, v0.4s, v1.4s238; CHECK-NEXT: ret239 %abd = call <4 x i32> @llvm.aarch64.neon.uabd.v4i32(<4 x i32> %lhs, <4 x i32> %rhs)240 ret <4 x i32> %abd241}242 243define <4 x i32> @test_uaba_v4i32(<4 x i32> %lhs, <4 x i32> %rhs) {244; CHECK-LABEL: test_uaba_v4i32:245; CHECK: // %bb.0:246; CHECK-NEXT: uaba v0.4s, v0.4s, v1.4s247; CHECK-NEXT: ret248 %abd = call <4 x i32> @llvm.aarch64.neon.uabd.v4i32(<4 x i32> %lhs, <4 x i32> %rhs)249 %aba = add <4 x i32> %lhs, %abd250 ret <4 x i32> %aba251}252 253define <4 x i32> @test_sabd_v4i32(<4 x i32> %lhs, <4 x i32> %rhs) {254; CHECK-LABEL: test_sabd_v4i32:255; CHECK: // %bb.0:256; CHECK-NEXT: sabd v0.4s, v0.4s, v1.4s257; CHECK-NEXT: ret258 %abd = call <4 x i32> @llvm.aarch64.neon.sabd.v4i32(<4 x i32> %lhs, <4 x i32> %rhs)259 ret <4 x i32> %abd260}261 262define <4 x i32> @test_saba_v4i32(<4 x i32> %lhs, <4 x i32> %rhs) {263; CHECK-LABEL: test_saba_v4i32:264; CHECK: // %bb.0:265; CHECK-NEXT: saba v0.4s, v0.4s, v1.4s266; CHECK-NEXT: ret267 %abd = call <4 x i32> @llvm.aarch64.neon.sabd.v4i32(<4 x i32> %lhs, <4 x i32> %rhs)268 %aba = add <4 x i32> %lhs, %abd269 ret <4 x i32> %aba270}271 272declare <2 x float> @llvm.aarch64.neon.fabd.v2f32(<2 x float>, <2 x float>)273 274define <2 x float> @test_fabd_v2f32(<2 x float> %lhs, <2 x float> %rhs) {275; CHECK-LABEL: test_fabd_v2f32:276; CHECK: // %bb.0:277; CHECK-NEXT: fabd v0.2s, v0.2s, v1.2s278; CHECK-NEXT: ret279 %abd = call <2 x float> @llvm.aarch64.neon.fabd.v2f32(<2 x float> %lhs, <2 x float> %rhs)280 ret <2 x float> %abd281}282 283declare <4 x float> @llvm.aarch64.neon.fabd.v4f32(<4 x float>, <4 x float>)284 285define <4 x float> @test_fabd_v4f32(<4 x float> %lhs, <4 x float> %rhs) {286; CHECK-LABEL: test_fabd_v4f32:287; CHECK: // %bb.0:288; CHECK-NEXT: fabd v0.4s, v0.4s, v1.4s289; CHECK-NEXT: ret290 %abd = call <4 x float> @llvm.aarch64.neon.fabd.v4f32(<4 x float> %lhs, <4 x float> %rhs)291 ret <4 x float> %abd292}293 294declare <2 x double> @llvm.aarch64.neon.fabd.v2f64(<2 x double>, <2 x double>)295 296define <2 x double> @test_fabd_v2f64(<2 x double> %lhs, <2 x double> %rhs) {297; CHECK-LABEL: test_fabd_v2f64:298; CHECK: // %bb.0:299; CHECK-NEXT: fabd v0.2d, v0.2d, v1.2d300; CHECK-NEXT: ret301 %abd = call <2 x double> @llvm.aarch64.neon.fabd.v2f64(<2 x double> %lhs, <2 x double> %rhs)302 ret <2 x double> %abd303}304 305define <8 x i16> @test_uabd_knownbits_vec8i16(<8 x i16> %lhs, <8 x i16> %rhs) {306; CHECK-SD-LABEL: test_uabd_knownbits_vec8i16:307; CHECK-SD: // %bb.0:308; CHECK-SD-NEXT: movi v2.8h, #15309; CHECK-SD-NEXT: and v0.16b, v0.16b, v2.16b310; CHECK-SD-NEXT: and v1.16b, v1.16b, v2.16b311; CHECK-SD-NEXT: uabd v0.8h, v0.8h, v1.8h312; CHECK-SD-NEXT: rev64 v0.8h, v0.8h313; CHECK-SD-NEXT: ext v0.16b, v0.16b, v0.16b, #8314; CHECK-SD-NEXT: ret315;316; CHECK-GI-LABEL: test_uabd_knownbits_vec8i16:317; CHECK-GI: // %bb.0:318; CHECK-GI-NEXT: movi v2.8h, #15319; CHECK-GI-NEXT: and v0.16b, v0.16b, v2.16b320; CHECK-GI-NEXT: and v1.16b, v1.16b, v2.16b321; CHECK-GI-NEXT: uabd v0.8h, v0.8h, v1.8h322; CHECK-GI-NEXT: rev64 v0.8h, v0.8h323; CHECK-GI-NEXT: ext v0.16b, v0.16b, v0.16b, #8324; CHECK-GI-NEXT: and v0.16b, v0.16b, v2.16b325; CHECK-GI-NEXT: ret326 %and1 = and <8 x i16> %lhs, <i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15>327 %and2 = and <8 x i16> %rhs, <i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15>328 %uabd = call <8 x i16> @llvm.aarch64.neon.uabd.v8i16(<8 x i16> %and1, <8 x i16> %and2)329 %suff = shufflevector <8 x i16> %uabd, <8 x i16> undef, <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>330 %res = and <8 x i16> %suff, <i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15>331 ret <8 x i16> %res332}333 334define <4 x i32> @knownbits_uabd_mask_and_shuffle_lshr(<4 x i32> %a0, <4 x i32> %a1) {335; CHECK-SD-LABEL: knownbits_uabd_mask_and_shuffle_lshr:336; CHECK-SD: // %bb.0:337; CHECK-SD-NEXT: movi v0.2d, #0000000000000000338; CHECK-SD-NEXT: ushr v0.4s, v0.4s, #17339; CHECK-SD-NEXT: ret340;341; CHECK-GI-LABEL: knownbits_uabd_mask_and_shuffle_lshr:342; CHECK-GI: // %bb.0:343; CHECK-GI-NEXT: movi v2.2d, #0x00ffff0000ffff344; CHECK-GI-NEXT: and v0.16b, v0.16b, v2.16b345; CHECK-GI-NEXT: and v1.16b, v1.16b, v2.16b346; CHECK-GI-NEXT: uabd v0.4s, v0.4s, v1.4s347; CHECK-GI-NEXT: rev64 v0.4s, v0.4s348; CHECK-GI-NEXT: ext v0.16b, v0.16b, v0.16b, #8349; CHECK-GI-NEXT: ushr v0.4s, v0.4s, #17350; CHECK-GI-NEXT: ret351 %1 = and <4 x i32> %a0, <i32 65535, i32 65535, i32 65535, i32 65535>352 %2 = and <4 x i32> %a1, <i32 65535, i32 65535, i32 65535, i32 65535>353 %3 = call <4 x i32> @llvm.aarch64.neon.uabd.v4i32(<4 x i32> %1, <4 x i32> %2)354 %4 = shufflevector <4 x i32> %3, <4 x i32> undef, <4 x i32> <i32 3, i32 2, i32 1, i32 0>355 %5 = lshr <4 x i32> %4, <i32 17, i32 17, i32 17, i32 17>356 ret <4 x i32> %5357}358 359define <4 x i32> @knownbits_mask_and_shuffle_lshr(<4 x i32> %a0, <4 x i32> %a1) {360; CHECK-SD-LABEL: knownbits_mask_and_shuffle_lshr:361; CHECK-SD: // %bb.0:362; CHECK-SD-NEXT: movi v0.2d, #0000000000000000363; CHECK-SD-NEXT: ret364;365; CHECK-GI-LABEL: knownbits_mask_and_shuffle_lshr:366; CHECK-GI: // %bb.0:367; CHECK-GI-NEXT: movi v2.4s, #127, msl #8368; CHECK-GI-NEXT: and v0.16b, v0.16b, v2.16b369; CHECK-GI-NEXT: and v1.16b, v1.16b, v2.16b370; CHECK-GI-NEXT: uabd v0.4s, v0.4s, v1.4s371; CHECK-GI-NEXT: ushr v0.4s, v0.4s, #17372; CHECK-GI-NEXT: ret373 %1 = and <4 x i32> %a0, <i32 32767, i32 32767, i32 32767, i32 32767>374 %2 = and <4 x i32> %a1, <i32 32767, i32 32767, i32 32767, i32 32767>375 %3 = call <4 x i32> @llvm.aarch64.neon.uabd.v4i32(<4 x i32> %1, <4 x i32> %2)376 %4 = shufflevector <4 x i32> %3, <4 x i32> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>377 %5 = lshr <4 x i32> %4, <i32 17, i32 17, i32 17, i32 17>378 ret <4 x i32> %5379}380 381define <4 x i32> @test_sabd_knownbits_vec4i32(<4 x i32> %lhs, <4 x i32> %rhs) {382; CHECK-SD-LABEL: test_sabd_knownbits_vec4i32:383; CHECK-SD: // %bb.0:384; CHECK-SD-NEXT: adrp x8, .LCPI31_0385; CHECK-SD-NEXT: adrp x9, .LCPI31_1386; CHECK-SD-NEXT: ldr q2, [x8, :lo12:.LCPI31_0]387; CHECK-SD-NEXT: ldr q3, [x9, :lo12:.LCPI31_1]388; CHECK-SD-NEXT: and v0.16b, v0.16b, v2.16b389; CHECK-SD-NEXT: and v1.16b, v1.16b, v3.16b390; CHECK-SD-NEXT: sabd v0.4s, v0.4s, v1.4s391; CHECK-SD-NEXT: movi v1.2d, #0x0000ff000000ff392; CHECK-SD-NEXT: mov v0.s[1], v0.s[0]393; CHECK-SD-NEXT: trn2 v0.4s, v0.4s, v0.4s394; CHECK-SD-NEXT: and v0.16b, v0.16b, v1.16b395; CHECK-SD-NEXT: ret396;397; CHECK-GI-LABEL: test_sabd_knownbits_vec4i32:398; CHECK-GI: // %bb.0:399; CHECK-GI-NEXT: adrp x8, .LCPI31_2400; CHECK-GI-NEXT: adrp x9, .LCPI31_1401; CHECK-GI-NEXT: ldr q2, [x8, :lo12:.LCPI31_2]402; CHECK-GI-NEXT: ldr q3, [x9, :lo12:.LCPI31_1]403; CHECK-GI-NEXT: adrp x8, .LCPI31_0404; CHECK-GI-NEXT: and v0.16b, v0.16b, v2.16b405; CHECK-GI-NEXT: and v1.16b, v1.16b, v3.16b406; CHECK-GI-NEXT: ldr q2, [x8, :lo12:.LCPI31_0]407; CHECK-GI-NEXT: movi v3.2d, #0x0000ff000000ff408; CHECK-GI-NEXT: sabd v0.4s, v0.4s, v1.4s409; CHECK-GI-NEXT: tbl v0.16b, { v0.16b, v1.16b }, v2.16b410; CHECK-GI-NEXT: and v0.16b, v0.16b, v3.16b411; CHECK-GI-NEXT: ret412 %and1 = and <4 x i32> %lhs, <i32 255, i32 -1, i32 -1, i32 255>413 %and2 = and <4 x i32> %rhs, <i32 255, i32 255, i32 -1, i32 -1>414 %abd = call <4 x i32> @llvm.aarch64.neon.sabd.v4i32(<4 x i32> %and1, <4 x i32> %and2)415 %s = shufflevector <4 x i32> %abd, <4 x i32> undef, <4 x i32> <i32 0, i32 0, i32 3, i32 3>416 %4 = and <4 x i32> %s, <i32 255, i32 255, i32 255, i32 255>417 ret <4 x i32> %4418}419 420define <4 x i32> @knownbits_sabd_and_mask(<4 x i32> %a0, <4 x i32> %a1) {421; CHECK-SD-LABEL: knownbits_sabd_and_mask:422; CHECK-SD: // %bb.0:423; CHECK-SD-NEXT: adrp x8, .LCPI32_0424; CHECK-SD-NEXT: ldr q2, [x8, :lo12:.LCPI32_0]425; CHECK-SD-NEXT: and v0.16b, v0.16b, v2.16b426; CHECK-SD-NEXT: and v1.16b, v1.16b, v2.16b427; CHECK-SD-NEXT: sabd v0.4s, v0.4s, v1.4s428; CHECK-SD-NEXT: zip2 v0.4s, v0.4s, v0.4s429; CHECK-SD-NEXT: ret430;431; CHECK-GI-LABEL: knownbits_sabd_and_mask:432; CHECK-GI: // %bb.0:433; CHECK-GI-NEXT: adrp x8, .LCPI32_1434; CHECK-GI-NEXT: ldr q2, [x8, :lo12:.LCPI32_1]435; CHECK-GI-NEXT: adrp x8, .LCPI32_0436; CHECK-GI-NEXT: and v0.16b, v0.16b, v2.16b437; CHECK-GI-NEXT: and v1.16b, v1.16b, v2.16b438; CHECK-GI-NEXT: ldr q2, [x8, :lo12:.LCPI32_0]439; CHECK-GI-NEXT: sabd v0.4s, v0.4s, v1.4s440; CHECK-GI-NEXT: tbl v0.16b, { v0.16b, v1.16b }, v2.16b441; CHECK-GI-NEXT: ret442 %1 = and <4 x i32> %a0, <i32 -1, i32 -1, i32 255, i32 4085>443 %2 = and <4 x i32> %a1, <i32 -1, i32 -1, i32 255, i32 4085>444 %3 = call <4 x i32> @llvm.aarch64.neon.sabd.v4i32(<4 x i32> %1, <4 x i32> %2)445 %4 = shufflevector <4 x i32> %3, <4 x i32> undef, <4 x i32> <i32 2, i32 2, i32 3, i32 3>446 ret <4 x i32> %4447}448 449define <4 x i32> @knownbits_sabd_and_or_mask(<4 x i32> %a0, <4 x i32> %a1) {450; CHECK-SD-LABEL: knownbits_sabd_and_or_mask:451; CHECK-SD: // %bb.0:452; CHECK-SD-NEXT: movi v0.2d, #0000000000000000453; CHECK-SD-NEXT: ret454;455; CHECK-GI-LABEL: knownbits_sabd_and_or_mask:456; CHECK-GI: // %bb.0:457; CHECK-GI-NEXT: adrp x8, .LCPI33_1458; CHECK-GI-NEXT: movi v3.2d, #0x00ffff0000ffff459; CHECK-GI-NEXT: ldr q2, [x8, :lo12:.LCPI33_1]460; CHECK-GI-NEXT: adrp x8, .LCPI33_0461; CHECK-GI-NEXT: and v0.16b, v0.16b, v2.16b462; CHECK-GI-NEXT: and v1.16b, v1.16b, v2.16b463; CHECK-GI-NEXT: ldr q2, [x8, :lo12:.LCPI33_0]464; CHECK-GI-NEXT: orr v0.16b, v0.16b, v3.16b465; CHECK-GI-NEXT: orr v1.16b, v1.16b, v3.16b466; CHECK-GI-NEXT: uabd v0.4s, v0.4s, v1.4s467; CHECK-GI-NEXT: tbl v0.16b, { v0.16b, v1.16b }, v2.16b468; CHECK-GI-NEXT: ret469 %1 = and <4 x i32> %a0, <i32 -1, i32 -1, i32 255, i32 4085>470 %2 = or <4 x i32> %1, <i32 65535, i32 65535, i32 65535, i32 65535>471 %3 = and <4 x i32> %a1, <i32 -1, i32 -1, i32 255, i32 4085>472 %4 = or <4 x i32> %3, <i32 65535, i32 65535, i32 65535, i32 65535>473 %5 = call <4 x i32> @llvm.aarch64.neon.uabd.v4i32(<4 x i32> %2, <4 x i32> %4)474 %6 = shufflevector <4 x i32> %5, <4 x i32> undef, <4 x i32> <i32 2, i32 2, i32 3, i32 3>475 ret <4 x i32> %6476}477 478define <4 x i32> @knownbits_sabd_and_xor_mask(<4 x i32> %a0, <4 x i32> %a1) {479; CHECK-SD-LABEL: knownbits_sabd_and_xor_mask:480; CHECK-SD: // %bb.0:481; CHECK-SD-NEXT: adrp x8, .LCPI34_0482; CHECK-SD-NEXT: movi v3.2d, #0x00ffff0000ffff483; CHECK-SD-NEXT: ldr q2, [x8, :lo12:.LCPI34_0]484; CHECK-SD-NEXT: and v0.16b, v0.16b, v2.16b485; CHECK-SD-NEXT: and v1.16b, v1.16b, v2.16b486; CHECK-SD-NEXT: eor v0.16b, v0.16b, v3.16b487; CHECK-SD-NEXT: eor v1.16b, v1.16b, v3.16b488; CHECK-SD-NEXT: sabd v0.4s, v0.4s, v1.4s489; CHECK-SD-NEXT: zip2 v0.4s, v0.4s, v0.4s490; CHECK-SD-NEXT: ret491;492; CHECK-GI-LABEL: knownbits_sabd_and_xor_mask:493; CHECK-GI: // %bb.0:494; CHECK-GI-NEXT: adrp x8, .LCPI34_1495; CHECK-GI-NEXT: movi v3.2d, #0x00ffff0000ffff496; CHECK-GI-NEXT: ldr q2, [x8, :lo12:.LCPI34_1]497; CHECK-GI-NEXT: adrp x8, .LCPI34_0498; CHECK-GI-NEXT: and v0.16b, v0.16b, v2.16b499; CHECK-GI-NEXT: and v1.16b, v1.16b, v2.16b500; CHECK-GI-NEXT: ldr q2, [x8, :lo12:.LCPI34_0]501; CHECK-GI-NEXT: eor v0.16b, v0.16b, v3.16b502; CHECK-GI-NEXT: eor v1.16b, v1.16b, v3.16b503; CHECK-GI-NEXT: sabd v0.4s, v0.4s, v1.4s504; CHECK-GI-NEXT: tbl v0.16b, { v0.16b, v1.16b }, v2.16b505; CHECK-GI-NEXT: ret506 %1 = and <4 x i32> %a0, <i32 -1, i32 -1, i32 255, i32 4085>507 %2 = xor <4 x i32> %1, <i32 65535, i32 65535, i32 65535, i32 65535>508 %3 = and <4 x i32> %a1, <i32 -1, i32 -1, i32 255, i32 4085>509 %4 = xor <4 x i32> %3, <i32 65535, i32 65535, i32 65535, i32 65535>510 %5 = call <4 x i32> @llvm.aarch64.neon.sabd.v4i32(<4 x i32> %2, <4 x i32> %4)511 %6 = shufflevector <4 x i32> %5, <4 x i32> undef, <4 x i32> <i32 2, i32 2, i32 3, i32 3>512 ret <4 x i32> %6513}514 515define <4 x i32> @knownbits_sabd_and_shl_mask(<4 x i32> %a0, <4 x i32> %a1) {516; CHECK-SD-LABEL: knownbits_sabd_and_shl_mask:517; CHECK-SD: // %bb.0:518; CHECK-SD-NEXT: movi v0.2d, #0000000000000000519; CHECK-SD-NEXT: ret520;521; CHECK-GI-LABEL: knownbits_sabd_and_shl_mask:522; CHECK-GI: // %bb.0:523; CHECK-GI-NEXT: adrp x8, .LCPI35_1524; CHECK-GI-NEXT: ldr q2, [x8, :lo12:.LCPI35_1]525; CHECK-GI-NEXT: adrp x8, .LCPI35_0526; CHECK-GI-NEXT: and v0.16b, v0.16b, v2.16b527; CHECK-GI-NEXT: and v1.16b, v1.16b, v2.16b528; CHECK-GI-NEXT: ldr q2, [x8, :lo12:.LCPI35_0]529; CHECK-GI-NEXT: shl v0.4s, v0.4s, #17530; CHECK-GI-NEXT: shl v1.4s, v1.4s, #17531; CHECK-GI-NEXT: sabd v0.4s, v0.4s, v1.4s532; CHECK-GI-NEXT: tbl v0.16b, { v0.16b, v1.16b }, v2.16b533; CHECK-GI-NEXT: ret534 %1 = and <4 x i32> %a0, <i32 -65536, i32 -7, i32 -7, i32 -65536>535 %2 = shl <4 x i32> %1, <i32 17, i32 17, i32 17, i32 17>536 %3 = and <4 x i32> %a1, <i32 -65536, i32 -7, i32 -7, i32 -65536>537 %4 = shl <4 x i32> %3, <i32 17, i32 17, i32 17, i32 17>538 %5 = call <4 x i32> @llvm.aarch64.neon.sabd.v4i32(<4 x i32> %2, <4 x i32> %4)539 %6 = shufflevector <4 x i32> %5, <4 x i32> undef, <4 x i32> <i32 0, i32 0, i32 3, i32 3>540 ret <4 x i32> %6541}542 543define <4 x i32> @knownbits_sabd_and_mul_mask(<4 x i32> %a0, <4 x i32> %a1) {544; CHECK-SD-LABEL: knownbits_sabd_and_mul_mask:545; CHECK-SD: // %bb.0:546; CHECK-SD-NEXT: adrp x8, .LCPI36_0547; CHECK-SD-NEXT: ldr q2, [x8, :lo12:.LCPI36_0]548; CHECK-SD-NEXT: and v3.16b, v0.16b, v2.16b549; CHECK-SD-NEXT: and v2.16b, v1.16b, v2.16b550; CHECK-SD-NEXT: mul v0.4s, v0.4s, v3.4s551; CHECK-SD-NEXT: mul v1.4s, v1.4s, v2.4s552; CHECK-SD-NEXT: sabd v0.4s, v0.4s, v1.4s553; CHECK-SD-NEXT: mov v0.s[1], v0.s[0]554; CHECK-SD-NEXT: trn2 v0.4s, v0.4s, v0.4s555; CHECK-SD-NEXT: ret556;557; CHECK-GI-LABEL: knownbits_sabd_and_mul_mask:558; CHECK-GI: // %bb.0:559; CHECK-GI-NEXT: adrp x8, .LCPI36_1560; CHECK-GI-NEXT: ldr q2, [x8, :lo12:.LCPI36_1]561; CHECK-GI-NEXT: adrp x8, .LCPI36_0562; CHECK-GI-NEXT: and v3.16b, v0.16b, v2.16b563; CHECK-GI-NEXT: and v2.16b, v1.16b, v2.16b564; CHECK-GI-NEXT: mul v0.4s, v0.4s, v3.4s565; CHECK-GI-NEXT: mul v1.4s, v1.4s, v2.4s566; CHECK-GI-NEXT: ldr q2, [x8, :lo12:.LCPI36_0]567; CHECK-GI-NEXT: sabd v0.4s, v0.4s, v1.4s568; CHECK-GI-NEXT: tbl v0.16b, { v0.16b, v1.16b }, v2.16b569; CHECK-GI-NEXT: ret570 %1 = and <4 x i32> %a0, <i32 -65536, i32 -7, i32 -7, i32 -65536>571 %2 = mul <4 x i32> %a0, %1572 %3 = and <4 x i32> %a1, <i32 -65536, i32 -7, i32 -7, i32 -65536>573 %4 = mul <4 x i32> %a1, %3574 %5 = call <4 x i32> @llvm.aarch64.neon.sabd.v4i32(<4 x i32> %2, <4 x i32> %4)575 %6 = shufflevector <4 x i32> %5, <4 x i32> undef, <4 x i32> <i32 0, i32 0, i32 3, i32 3>576 ret <4 x i32> %6577}578 579define <4 x i16> @trunc_abdu_foldable(<4 x i16> %a, <4 x i16> %b) {580; CHECK-SD-LABEL: trunc_abdu_foldable:581; CHECK-SD: // %bb.0:582; CHECK-SD-NEXT: uabd v0.4h, v0.4h, v1.4h583; CHECK-SD-NEXT: ret584;585; CHECK-GI-LABEL: trunc_abdu_foldable:586; CHECK-GI: // %bb.0:587; CHECK-GI-NEXT: ushll v0.4s, v0.4h, #0588; CHECK-GI-NEXT: ushll v1.4s, v1.4h, #0589; CHECK-GI-NEXT: uabd v0.4s, v0.4s, v1.4s590; CHECK-GI-NEXT: xtn v0.4h, v0.4s591; CHECK-GI-NEXT: ret592 %ext_a = zext <4 x i16> %a to <4 x i32>593 %ext_b = zext <4 x i16> %b to <4 x i32>594 %abd = call <4 x i32> @llvm.aarch64.neon.uabd.v4i32(<4 x i32> %ext_a, <4 x i32> %ext_b)595 %trunc = trunc <4 x i32> %abd to <4 x i16>596 ret <4 x i16> %trunc597}598 599define <4 x i16> @trunc_abds_foldable(<4 x i16> %a, <4 x i16> %b) {600; CHECK-SD-LABEL: trunc_abds_foldable:601; CHECK-SD: // %bb.0:602; CHECK-SD-NEXT: sabd v0.4h, v0.4h, v1.4h603; CHECK-SD-NEXT: ret604;605; CHECK-GI-LABEL: trunc_abds_foldable:606; CHECK-GI: // %bb.0:607; CHECK-GI-NEXT: sshll v0.4s, v0.4h, #0608; CHECK-GI-NEXT: sshll v1.4s, v1.4h, #0609; CHECK-GI-NEXT: sabd v0.4s, v0.4s, v1.4s610; CHECK-GI-NEXT: xtn v0.4h, v0.4s611; CHECK-GI-NEXT: ret612 %a32 = sext <4 x i16> %a to <4 x i32>613 %b32 = sext <4 x i16> %b to <4 x i32>614 %abd32 = call <4 x i32> @llvm.aarch64.neon.sabd.v4i32(<4 x i32> %a32, <4 x i32> %b32)615 %res16 = trunc <4 x i32> %abd32 to <4 x i16>616 ret <4 x i16> %res16617}618 619define <4 x i16> @trunc_abdu_not_foldable(<4 x i16> %a, <4 x i32> %b) {620; CHECK-LABEL: trunc_abdu_not_foldable:621; CHECK: // %bb.0:622; CHECK-NEXT: ushll v0.4s, v0.4h, #0623; CHECK-NEXT: uabd v0.4s, v0.4s, v1.4s624; CHECK-NEXT: xtn v0.4h, v0.4s625; CHECK-NEXT: ret626 %ext_a = zext <4 x i16> %a to <4 x i32>627 %abd = call <4 x i32> @llvm.aarch64.neon.uabd.v4i32(<4 x i32> %ext_a, <4 x i32> %b)628 %trunc = trunc <4 x i32> %abd to <4 x i16>629 ret <4 x i16> %trunc630}631 632define <4 x i16> @truncate_abds_testcase1(<4 x i16> %a, <4 x i32> %b) {633; CHECK-LABEL: truncate_abds_testcase1:634; CHECK: // %bb.0:635; CHECK-NEXT: sshll v0.4s, v0.4h, #0636; CHECK-NEXT: sabd v0.4s, v0.4s, v1.4s637; CHECK-NEXT: xtn v0.4h, v0.4s638; CHECK-NEXT: ret639 %a32 = sext <4 x i16> %a to <4 x i32>640 %abd32 = call <4 x i32> @llvm.aarch64.neon.sabd.v4i32(<4 x i32> %a32, <4 x i32> %b)641 %res16 = trunc <4 x i32> %abd32 to <4 x i16>642 ret <4 x i16> %res16643}644