mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-18 16:03:17 +00:00
[AArch64] Fix miscompile of sdiv-by-power-of-2.
When the constant divisor was larger than 32bits, then the optimized code generated for the AArch64 backend would emit the wrong code, because the shift was defined as a shift of a 32bit constant '(1<<Lg2(divisor))' and we would loose the upper 32bits. This fixes rdar://problem/18678801. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@219934 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
3b72ec5083
commit
c40dab2069
@ -4515,9 +4515,8 @@ bool AArch64FastISel::selectSDiv(const Instruction *I) {
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned Pow2MinusOne = (1 << Lg2) - 1;
|
||||
unsigned AddReg = emitAddSub_ri(/*UseAdd=*/true, VT, Src0Reg,
|
||||
/*IsKill=*/false, Pow2MinusOne);
|
||||
int64_t Pow2MinusOne = (1ULL << Lg2) - 1;
|
||||
unsigned AddReg = emitAdd_ri_(VT, Src0Reg, /*IsKill=*/false, Pow2MinusOne);
|
||||
if (!AddReg)
|
||||
return false;
|
||||
|
||||
|
@ -6822,7 +6822,7 @@ AArch64TargetLowering::BuildSDIVPow2(SDNode *N, const APInt &Divisor,
|
||||
SDValue N0 = N->getOperand(0);
|
||||
unsigned Lg2 = Divisor.countTrailingZeros();
|
||||
SDValue Zero = DAG.getConstant(0, VT);
|
||||
SDValue Pow2MinusOne = DAG.getConstant((1 << Lg2) - 1, VT);
|
||||
SDValue Pow2MinusOne = DAG.getConstant((1ULL << Lg2) - 1, VT);
|
||||
|
||||
// Add (N0 < 0) ? Pow2 - 1 : 0;
|
||||
SDValue CCVal;
|
||||
|
@ -1,4 +1,5 @@
|
||||
; RUN: llc -mtriple=arm64-linux-gnu -o - %s | FileCheck %s
|
||||
; RUN: llc -mtriple=arm64-linux-gnu -fast-isel=0 -verify-machineinstrs < %s | FileCheck %s
|
||||
; RUN: llc -mtriple=arm64-linux-gnu -fast-isel=1 -verify-machineinstrs < %s | FileCheck %s
|
||||
|
||||
define i32 @test1(i32 %x) {
|
||||
; CHECK-LABEL: test1
|
||||
@ -59,3 +60,15 @@ define i64 @test6(i64 %x) {
|
||||
%div = sdiv i64 %x, 64
|
||||
ret i64 %div
|
||||
}
|
||||
|
||||
define i64 @test7(i64 %x) {
|
||||
; CHECK-LABEL: test7
|
||||
; CHECK: orr [[REG:x[0-9]+]], xzr, #0xffffffffffff
|
||||
; CHECK: add x8, x0, [[REG]]
|
||||
; CHECK: cmp x0, #0
|
||||
; CHECK: csel x8, x8, x0, lt
|
||||
; CHECK: asr x0, x8, #48
|
||||
%div = sdiv i64 %x, 281474976710656
|
||||
ret i64 %div
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user