diff --git a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp index cafd63437df92..99794d690a91c 100644 --- a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp +++ b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp @@ -223,6 +223,14 @@ void GISelValueTracking::computeKnownBitsImpl(Register R, KnownBits &Known, } break; } + case TargetOpcode::G_SPLAT_VECTOR: { + computeKnownBitsImpl(MI.getOperand(1).getReg(), Known, APInt(1, 1), + Depth + 1); + // Implicitly truncate the bits to match the official semantics of + // G_SPLAT_VECTOR. + Known = Known.trunc(BitWidth); + break; + } case TargetOpcode::COPY: case TargetOpcode::G_PHI: case TargetOpcode::PHI: { @@ -904,6 +912,15 @@ unsigned GISelValueTracking::computeNumSignBits(Register R, } break; } + case TargetOpcode::G_SPLAT_VECTOR: { + // Check if the sign bits of source go down as far as the truncated value. + Register Src = MI.getOperand(1).getReg(); + unsigned NumSrcSignBits = computeNumSignBits(Src, APInt(1, 1), Depth + 1); + unsigned NumSrcBits = MRI.getType(Src).getSizeInBits(); + if (NumSrcSignBits > (NumSrcBits - TyBits)) + return NumSrcSignBits - (NumSrcBits - TyBits); + break; + } case TargetOpcode::G_INTRINSIC: case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS: case TargetOpcode::G_INTRINSIC_CONVERGENT: @@ -939,7 +956,7 @@ unsigned GISelValueTracking::computeNumSignBits(Register R, unsigned GISelValueTracking::computeNumSignBits(Register R, unsigned Depth) { LLT Ty = MRI.getType(R); APInt DemandedElts = - Ty.isVector() ? APInt::getAllOnes(Ty.getNumElements()) : APInt(1, 1); + Ty.isFixedVector() ? APInt::getAllOnes(Ty.getNumElements()) : APInt(1, 1); return computeNumSignBits(R, DemandedElts, Depth); } diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-sve-splat.mir b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-sve-splat.mir new file mode 100644 index 0000000000000..27c11ee1641e9 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-sve-splat.mir @@ -0,0 +1,35 @@ +# NOTE: Assertions have been autogenerated by utils/update_givaluetracking_test_checks.py UTC_ARGS: --version 5 +# RUN: llc -mtriple aarch64 -mattr=+sve -passes="print" %s -o - 2>&1 | FileCheck %s + +--- +name: Scalable +body: | + bb.1: + ; CHECK-LABEL: name: @Scalable + ; CHECK-NEXT: %0:_ KnownBits:0000000000001010 SignBits:12 + ; CHECK-NEXT: %1:_ KnownBits:0000000000001010 SignBits:12 + %0:_(s16) = G_CONSTANT i16 10 + %1:_() = G_SPLAT_VECTOR %0(s16) +... +--- +name: Scalable_trunc +body: | + bb.1: + ; CHECK-LABEL: name: @Scalable_trunc + ; CHECK-NEXT: %0:_ KnownBits:00000000000000000000000000001010 SignBits:28 + ; CHECK-NEXT: %1:_ KnownBits:0000000000001010 SignBits:12 + %0:_(s32) = G_CONSTANT i32 10 + %1:_() = G_SPLAT_VECTOR %0(s32) +... +--- +name: Scalable_signbits +body: | + bb.1: + ; CHECK-LABEL: name: @Scalable_signbits + ; CHECK-NEXT: %0:_ KnownBits:???????????????? SignBits:1 + ; CHECK-NEXT: %1:_ KnownBits:???????????????????????????????? SignBits:17 + ; CHECK-NEXT: %2:_ KnownBits:???????????????????????????????? SignBits:17 + %0:_(s16) = COPY $h0 + %1:_(s32) = G_SEXT %0(s16) + %2:_() = G_SPLAT_VECTOR %1(s32) +...