diff --git a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp index f0b455fbdc7d0..a00e17cb3e441 100644 --- a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp +++ b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp @@ -285,6 +285,30 @@ void GISelValueTracking::computeKnownBitsImpl(Register R, KnownBits &Known, } break; } + case TargetOpcode::G_STEP_VECTOR: { + APInt Step = MI.getOperand(1).getCImm()->getValue(); + + if (Step.isPowerOf2()) + Known.Zero.setLowBits(Step.logBase2()); + + if (!isUIntN(BitWidth, DstTy.getElementCount().getKnownMinValue())) + break; + + const APInt MinNumElts = + APInt(BitWidth, DstTy.getElementCount().getKnownMinValue()); + const Function &F = getMachineFunction().getFunction(); + bool Overflow; + const APInt MaxNumElts = getVScaleRange(&F, BitWidth) + .getUnsignedMax() + .umul_ov(MinNumElts, Overflow); + if (Overflow) + break; + const APInt MaxValue = (MaxNumElts - 1).umul_ov(Step, Overflow); + if (Overflow) + break; + Known.Zero.setHighBits(MaxValue.countl_zero()); + break; + } case TargetOpcode::G_CONSTANT: { Known = KnownBits::makeConstant(MI.getOperand(1).getCImm()->getValue()); break; diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-stepvector.mir b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-stepvector.mir new file mode 100644 index 0000000000000..0547ea829598a --- /dev/null +++ b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-stepvector.mir @@ -0,0 +1,116 @@ +# 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 + +--- | + define void @StepVector_One() { ret void } + define void @StepVector_Pow2() { ret void } + define void @StepVector_NonPow2() { ret void } + define void @StepVector_s8() { ret void } + define void @StepVector_s8_Pow2() { ret void } + define void @StepVector_s64() { ret void } + define void @StepVector_s64_Pow2() { ret void } + define void @StepVector_s128() { ret void } + define void @StepVector_s128_Pow2() { ret void } + define void @StepVector_ElementCountOverflowsBitWidth() { ret void } + define void @StepVector_Overflow_MaxNumElts() #0 { ret void } + define void @StepVector_Overflow_MaxValue() #1 { ret void } + + attributes #0 = { vscale_range(1, 16) } + attributes #1 = { vscale_range(1, 16) } +... +--- +name: StepVector_One +body: | + bb.0: + ; CHECK-LABEL: name: @StepVector_One + ; CHECK-NEXT: %0:_ KnownBits:???????????????????????????????? SignBits:1 + %0:_() = G_STEP_VECTOR i32 1 +... +--- +name: StepVector_Pow2 +body: | + bb.0: + ; CHECK-LABEL: name: @StepVector_Pow2 + ; CHECK-NEXT: %0:_ KnownBits:????????????????????????????0000 SignBits:1 + %0:_() = G_STEP_VECTOR i32 16 +... +--- +name: StepVector_NonPow2 +body: | + bb.0: + ; CHECK-LABEL: name: @StepVector_NonPow2 + ; CHECK-NEXT: %0:_ KnownBits:???????????????????????????????? SignBits:1 + %0:_() = G_STEP_VECTOR i32 3 +... +--- +name: StepVector_s8 +body: | + bb.0: + ; CHECK-LABEL: name: @StepVector_s8 + ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1 + %0:_() = G_STEP_VECTOR i8 1 +... +--- +name: StepVector_s8_Pow2 +body: | + bb.0: + ; CHECK-LABEL: name: @StepVector_s8_Pow2 + ; CHECK-NEXT: %0:_ KnownBits:??????00 SignBits:1 + %0:_() = G_STEP_VECTOR i8 4 +... +--- +name: StepVector_s64 +body: | + bb.0: + ; CHECK-LABEL: name: @StepVector_s64 + ; CHECK-NEXT: %0:_ KnownBits:???????????????????????????????????????????????????????????????? SignBits:1 + %0:_() = G_STEP_VECTOR i64 1 +... +--- +name: StepVector_s64_Pow2 +body: | + bb.0: + ; CHECK-LABEL: name: @StepVector_s64_Pow2 + ; CHECK-NEXT: %0:_ KnownBits:?????????????????????????????????????????????????????????????000 SignBits:1 + %0:_() = G_STEP_VECTOR i64 8 +... +--- +name: StepVector_s128 +body: | + bb.0: + ; CHECK-LABEL: name: @StepVector_s128 + ; CHECK-NEXT: %0:_ KnownBits:???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? SignBits:1 + %0:_() = G_STEP_VECTOR i128 1 +... +--- +name: StepVector_s128_Pow2 +body: | + bb.0: + ; CHECK-LABEL: name: @StepVector_s128_Pow2 + ; CHECK-NEXT: %0:_ KnownBits:?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????000 SignBits:1 + %0:_() = G_STEP_VECTOR i128 8 +... +--- +name: StepVector_ElementCountOverflowsBitWidth +body: | + bb.0: + ; CHECK-LABEL: name: @StepVector_ElementCountOverflowsBitWidth + ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1 + %0:_() = G_STEP_VECTOR i8 3 +... +--- +name: StepVector_Overflow_MaxNumElts +body: | + bb.0: + ; CHECK-LABEL: name: @StepVector_Overflow_MaxNumElts + ; CHECK-NEXT: %0:_ KnownBits:???????? SignBits:1 + %0:_() = G_STEP_VECTOR i8 3 +... +--- +name: StepVector_Overflow_MaxValue +body: | + bb.0: + ; CHECK-LABEL: name: @StepVector_Overflow_MaxValue + ; CHECK-NEXT: %0:_ KnownBits:???????????????????????????????? SignBits:1 + %0:_() = G_STEP_VECTOR i32 1073741825 +...