From 68a9e9ca3e9324c48bdd541fdbc79e002ef7f2bb Mon Sep 17 00:00:00 2001 From: Dhruva Date: Fri, 20 Mar 2026 22:38:14 +0530 Subject: [PATCH] [GlobalISel] Add G_ABDU and G_ABDS to computeKnownBits. (#186822) This code is adapted from `SelectionDAG::computeKnownBits` part of #150515 ticks off ABDS & ABDU --- .../CodeGen/GlobalISel/GISelValueTracking.cpp | 26 ++++++ .../AArch64/GlobalISel/knownbits-abds.mir | 76 ++++++++++++++++ .../AArch64/GlobalISel/knownbits-abdu.mir | 88 +++++++++++++++++++ .../CodeGen/AArch64/arm64-neon-aba-abd.ll | 29 ++---- 4 files changed, 199 insertions(+), 20 deletions(-) create mode 100644 llvm/test/CodeGen/AArch64/GlobalISel/knownbits-abds.mir create mode 100644 llvm/test/CodeGen/AArch64/GlobalISel/knownbits-abdu.mir diff --git a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp index 245ade77f736..b8613aabe7fd 100644 --- a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp +++ b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp @@ -372,6 +372,32 @@ void GISelValueTracking::computeKnownBitsImpl(Register R, KnownBits &Known, Known = KnownBits::mulhs(Known, Known2); break; } + case TargetOpcode::G_ABDU: { + computeKnownBitsImpl(MI.getOperand(2).getReg(), Known, DemandedElts, + Depth + 1); + computeKnownBitsImpl(MI.getOperand(1).getReg(), Known2, DemandedElts, + Depth + 1); + Known = KnownBits::abdu(Known, Known2); + break; + } + case TargetOpcode::G_ABDS: { + computeKnownBitsImpl(MI.getOperand(2).getReg(), Known, DemandedElts, + Depth + 1); + computeKnownBitsImpl(MI.getOperand(1).getReg(), Known2, DemandedElts, + Depth + 1); + Known = KnownBits::abds(Known, Known2); + + unsigned SignBits1 = + computeNumSignBits(MI.getOperand(2).getReg(), DemandedElts, Depth + 1); + if (SignBits1 == 1) { + break; + } + unsigned SignBits0 = + computeNumSignBits(MI.getOperand(1).getReg(), DemandedElts, Depth + 1); + + Known.Zero.setHighBits(std::min(SignBits0, SignBits1) - 1); + break; + } case TargetOpcode::G_UDIV: { computeKnownBitsImpl(MI.getOperand(1).getReg(), Known, DemandedElts, Depth + 1); diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-abds.mir b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-abds.mir new file mode 100644 index 000000000000..02cbc98af950 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-abds.mir @@ -0,0 +1,76 @@ +# NOTE: Assertions have been autogenerated by utils/update_givaluetracking_test_checks.py UTC_ARGS: --version 6 +# RUN: llc -mtriple=aarch64 -passes="print" -filetype=null %s 2>&1 | FileCheck %s + +--- +name: Cst +body: | + bb.0: + ; CHECK-LABEL: name: @Cst + ; CHECK-NEXT: %0:_ KnownBits:00001010 SignBits:4 + ; CHECK-NEXT: %1:_ KnownBits:00000011 SignBits:6 + ; CHECK-NEXT: %2:_ KnownBits:00000111 SignBits:5 + %0:_(s8) = G_CONSTANT i8 10 + %1:_(s8) = G_CONSTANT i8 3 + %2:_(s8) = G_ABDS %0, %1 +... +--- +name: PartialKnown +body: | + bb.0: + ; CHECK-LABEL: name: @PartialKnown + ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1 + ; CHECK-NEXT: %1:_ KnownBits:00001111 SignBits:4 + ; CHECK-NEXT: %2:_ KnownBits:0000???? SignBits:4 + ; CHECK-NEXT: %3:_ KnownBits:00000100 SignBits:5 + ; CHECK-NEXT: %4:_ KnownBits:0000???? SignBits:4 + %0:_(s8) = G_IMPLICIT_DEF + %1:_(s8) = G_CONSTANT i8 15 + %2:_(s8) = G_AND %0, %1 + %3:_(s8) = G_CONSTANT i8 4 + %4:_(s8) = G_ABDS %2, %3 +... + +--- +name: SignBits +body: | + bb.0: + ; CHECK-LABEL: name: @SignBits + ; CHECK-NEXT: %0:_ KnownBits:???????????????????????????????? SignBits:1 + ; CHECK-NEXT: %1:_ KnownBits:???????????????????????????????? SignBits:1 + ; CHECK-NEXT: %2:_ KnownBits:???????????????????????????????? SignBits:25 + ; CHECK-NEXT: %3:_ KnownBits:???????????????????????????????? SignBits:25 + ; CHECK-NEXT: %4:_ KnownBits:000000000000000000000000???????? SignBits:24 + %0:_(s32) = COPY $w0 + %1:_(s32) = COPY $w1 + %2:_(s32) = G_SEXT_INREG %0, 8 + %3:_(s32) = G_SEXT_INREG %1, 8 + %4:_(s32) = G_ABDS %2, %3 +... +--- +name: SignBitsAsymmetric +body: | + bb.0: + ; CHECK-LABEL: name: @SignBitsAsymmetric + ; CHECK-NEXT: %0:_ KnownBits:???????????????????????????????? SignBits:1 + ; CHECK-NEXT: %1:_ KnownBits:???????????????????????????????? SignBits:1 + ; CHECK-NEXT: %2:_ KnownBits:???????????????????????????????? SignBits:25 + ; CHECK-NEXT: %3:_ KnownBits:???????????????????????????????? SignBits:17 + ; CHECK-NEXT: %4:_ KnownBits:0000000000000000???????????????? SignBits:16 + %0:_(s32) = COPY $w0 + %1:_(s32) = COPY $w1 + %2:_(s32) = G_SEXT_INREG %0, 8 + %3:_(s32) = G_SEXT_INREG %1, 16 + %4:_(s32) = G_ABDS %2, %3 +... +--- +name: Unknown +body: | + bb.0: + ; CHECK-LABEL: name: @Unknown + ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1 + ; CHECK-NEXT: %1:_ KnownBits:???????? SignBits:1 + ; CHECK-NEXT: %2:_ KnownBits:???????? SignBits:1 + %0:_(s8) = COPY $b0 + %1:_(s8) = COPY $b1 + %2:_(s8) = G_ABDS %0, %1 +... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-abdu.mir b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-abdu.mir new file mode 100644 index 000000000000..aa624bf377e4 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-abdu.mir @@ -0,0 +1,88 @@ +# NOTE: Assertions have been autogenerated by utils/update_givaluetracking_test_checks.py UTC_ARGS: --version 6 +# RUN: llc -mtriple aarch64 -passes="print" %s -filetype=null 2>&1 | FileCheck %s + +--- +name: Cst +body: | + bb.0: + ; CHECK-LABEL: name: @Cst + ; CHECK-NEXT: %0:_ KnownBits:00000101 SignBits:5 + ; CHECK-NEXT: %1:_ KnownBits:00000011 SignBits:6 + ; CHECK-NEXT: %2:_ KnownBits:00000010 SignBits:6 + %0:_(s8) = G_CONSTANT i8 5 + %1:_(s8) = G_CONSTANT i8 3 + %2:_(s8) = G_ABDU %0, %1 +... +--- +name: CstZero +body: | + bb.0: + ; CHECK-LABEL: name: @CstZero + ; CHECK-NEXT: %0:_ KnownBits:11111111 SignBits:8 + ; CHECK-NEXT: %1:_ KnownBits:00000000 SignBits:8 + ; CHECK-NEXT: %2:_ KnownBits:11111111 SignBits:8 + %0:_(s8) = G_CONSTANT i8 255 + %1:_(s8) = G_CONSTANT i8 0 + %2:_(s8) = G_ABDU %0, %1 +... +--- +name: ScalarZero +body: | + bb.0: + ; CHECK-LABEL: name: @ScalarZero + ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1 + ; CHECK-NEXT: %1:_ KnownBits:00000000 SignBits:8 + ; CHECK-NEXT: %2:_ KnownBits:???????? SignBits:1 + %0:_(s8) = COPY $b0 + %1:_(s8) = G_CONSTANT i8 0 + %2:_(s8) = G_ABDU %0, %1 +... +--- +name: PartialKnown +body: | + bb.0: + + ; CHECK-LABEL: name: @PartialKnown + ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1 + ; CHECK-NEXT: %1:_ KnownBits:00001111 SignBits:4 + ; CHECK-NEXT: %2:_ KnownBits:0000???? SignBits:4 + ; CHECK-NEXT: %3:_ KnownBits:00000100 SignBits:5 + ; CHECK-NEXT: %4:_ KnownBits:0000???? SignBits:4 + %0:_(s8) = G_IMPLICIT_DEF + %1:_(s8) = G_CONSTANT i8 15 + %2:_(s8) = G_AND %0, %1 + %3:_(s8) = G_CONSTANT i8 4 + %4:_(s8) = G_ABDU %2, %3 +... +--- +name: NoSignBitsPath +body: | + bb.0: + ; CHECK-LABEL: name: @NoSignBitsPath + ; CHECK-NEXT: %0:_ KnownBits:???????????????????????????????? SignBits:1 + ; CHECK-NEXT: %1:_ KnownBits:???????????????????????????????? SignBits:1 + ; CHECK-NEXT: %2:_ KnownBits:???????????????????????????????? SignBits:25 + ; CHECK-NEXT: %3:_ KnownBits:???????????????????????????????? SignBits:25 + ; CHECK-NEXT: %4:_ KnownBits:???????????????????????????????? SignBits:1 + %0:_(s32) = COPY $w0 + %1:_(s32) = COPY $w1 + %2:_(s32) = G_SEXT_INREG %0, 8 + %3:_(s32) = G_SEXT_INREG %1, 8 + %4:_(s32) = G_ABDU %2, %3 +... +--- +name: VecCst +body: | + bb.0: + ; CHECK-LABEL: name: @VecCst + ; CHECK-NEXT: %0:_ KnownBits:00000101 SignBits:5 + ; CHECK-NEXT: %1:_ KnownBits:00000011 SignBits:6 + ; CHECK-NEXT: %2:_ KnownBits:00000??1 SignBits:5 + ; CHECK-NEXT: %3:_ KnownBits:00000??1 SignBits:5 + ; CHECK-NEXT: %4:_ KnownBits:00000??0 SignBits:5 + %0:_(s8) = G_CONSTANT i8 5 + %1:_(s8) = G_CONSTANT i8 3 + %2:_(<2 x s8>) = G_BUILD_VECTOR %0, %1 + %3:_(<2 x s8>) = G_BUILD_VECTOR %0, %1 + %4:_(<2 x s8>) = G_ABDU %2, %3 +... diff --git a/llvm/test/CodeGen/AArch64/arm64-neon-aba-abd.ll b/llvm/test/CodeGen/AArch64/arm64-neon-aba-abd.ll index ccd1917ae3d8..062f5de38c45 100644 --- a/llvm/test/CodeGen/AArch64/arm64-neon-aba-abd.ll +++ b/llvm/test/CodeGen/AArch64/arm64-neon-aba-abd.ll @@ -303,26 +303,15 @@ define <2 x double> @test_fabd_v2f64(<2 x double> %lhs, <2 x double> %rhs) { } define <8 x i16> @test_uabd_knownbits_vec8i16(<8 x i16> %lhs, <8 x i16> %rhs) { -; CHECK-SD-LABEL: test_uabd_knownbits_vec8i16: -; CHECK-SD: // %bb.0: -; CHECK-SD-NEXT: movi v2.8h, #15 -; CHECK-SD-NEXT: and v0.16b, v0.16b, v2.16b -; CHECK-SD-NEXT: and v1.16b, v1.16b, v2.16b -; CHECK-SD-NEXT: uabd v0.8h, v0.8h, v1.8h -; CHECK-SD-NEXT: rev64 v0.8h, v0.8h -; CHECK-SD-NEXT: ext v0.16b, v0.16b, v0.16b, #8 -; CHECK-SD-NEXT: ret -; -; CHECK-GI-LABEL: test_uabd_knownbits_vec8i16: -; CHECK-GI: // %bb.0: -; CHECK-GI-NEXT: movi v2.8h, #15 -; CHECK-GI-NEXT: and v0.16b, v0.16b, v2.16b -; CHECK-GI-NEXT: and v1.16b, v1.16b, v2.16b -; CHECK-GI-NEXT: uabd v0.8h, v0.8h, v1.8h -; CHECK-GI-NEXT: rev64 v0.8h, v0.8h -; CHECK-GI-NEXT: ext v0.16b, v0.16b, v0.16b, #8 -; CHECK-GI-NEXT: and v0.16b, v0.16b, v2.16b -; CHECK-GI-NEXT: ret +; CHECK-LABEL: test_uabd_knownbits_vec8i16: +; CHECK: // %bb.0: +; CHECK-NEXT: movi v2.8h, #15 +; CHECK-NEXT: and v0.16b, v0.16b, v2.16b +; CHECK-NEXT: and v1.16b, v1.16b, v2.16b +; CHECK-NEXT: uabd v0.8h, v0.8h, v1.8h +; CHECK-NEXT: rev64 v0.8h, v0.8h +; CHECK-NEXT: ext v0.16b, v0.16b, v0.16b, #8 +; CHECK-NEXT: ret %and1 = and <8 x i16> %lhs, %and2 = and <8 x i16> %rhs, %uabd = call <8 x i16> @llvm.aarch64.neon.uabd.v8i16(<8 x i16> %and1, <8 x i16> %and2)