diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.h b/llvm/lib/Target/AArch64/AArch64ISelLowering.h --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.h +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.h @@ -907,6 +907,8 @@ SDValue Chain, SDValue InFlag, SDValue PStateSM, bool Entry) const; + bool isVScaleKnownToBeAPowerOfTwo() const override; + // Normally SVE is only used for byte size vectors that do not fit within a // NEON vector. This changes when OverrideNEON is true, allowing SVE to be // used for 64bit and 128bit vectors as well. diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -6083,6 +6083,10 @@ return !Subtarget->useSVEForFixedLengthVectors(); } +bool AArch64TargetLowering::isVScaleKnownToBeAPowerOfTwo() const { + return true; +} + bool AArch64TargetLowering::useSVEForFixedLengthVectorVT( EVT VT, bool OverrideNEON) const { if (!VT.isFixedLengthVector() || !VT.isSimple()) diff --git a/llvm/test/CodeGen/AArch64/vscale-power-of-two.ll b/llvm/test/CodeGen/AArch64/vscale-power-of-two.ll --- a/llvm/test/CodeGen/AArch64/vscale-power-of-two.ll +++ b/llvm/test/CodeGen/AArch64/vscale-power-of-two.ll @@ -7,8 +7,8 @@ ; CHECK-NEXT: rdvl x8, #1 ; CHECK-NEXT: lsr x8, x8, #4 ; CHECK-NEXT: lsr x8, x8, #3 -; CHECK-NEXT: udiv x9, x0, x8 -; CHECK-NEXT: msub x0, x9, x8, x0 +; CHECK-NEXT: sub x8, x8, #1 +; CHECK-NEXT: and x0, x0, x8 ; CHECK-NEXT: ret %vscale = call i64 @llvm.vscale.i64() %shifted = lshr i64 %vscale, 3 @@ -21,8 +21,8 @@ ; CHECK: // %bb.0: ; CHECK-NEXT: rdvl x8, #1 ; CHECK-NEXT: lsr x8, x8, #4 -; CHECK-NEXT: udiv x9, x0, x8 -; CHECK-NEXT: msub x0, x9, x8, x0 +; CHECK-NEXT: sub x8, x8, #1 +; CHECK-NEXT: and x0, x0, x8 ; CHECK-NEXT: ret %vscale = call i64 @llvm.vscale.i64() %urem = urem i64 %TC, %vscale @@ -33,8 +33,8 @@ ; CHECK-LABEL: vscale_shl: ; CHECK: // %bb.0: ; CHECK-NEXT: cnth x8 -; CHECK-NEXT: udiv x9, x0, x8 -; CHECK-NEXT: msub x0, x9, x8, x0 +; CHECK-NEXT: sub x8, x8, #1 +; CHECK-NEXT: and x0, x0, x8 ; CHECK-NEXT: ret %vscale = call i64 @llvm.vscale.i64() %shifted = shl i64 %vscale, 3