[llvm] r219934 - [AArch64] Fix miscompile of sdiv-by-power-of-2.

Chad Rosier mcrosier at codeaurora.org
Thu Oct 16 11:15:26 PDT 2014


Thanks for catching this, Juergen.

> Author: ributzka
> Date: Thu Oct 16 11:41:15 2014
> New Revision: 219934
>
> URL: http://llvm.org/viewvc/llvm-project?rev=219934&view=rev
> Log:
> [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.
>
> Modified:
>     llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp
>     llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp
>     llvm/trunk/test/CodeGen/AArch64/sdivpow2.ll
>
> Modified: llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp?rev=219934&r1=219933&r2=219934&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp (original)
> +++ llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp Thu Oct 16 11:41:15
> 2014
> @@ -4515,9 +4515,8 @@ bool AArch64FastISel::selectSDiv(const 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;
>
>
> Modified: llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp?rev=219934&r1=219933&r2=219934&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp (original)
> +++ llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp Thu Oct 16
> 11:41:15 2014
> @@ -6822,7 +6822,7 @@ AArch64TargetLowering::BuildSDIVPow2(SDN
>    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;
>
> Modified: llvm/trunk/test/CodeGen/AArch64/sdivpow2.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/sdivpow2.ll?rev=219934&r1=219933&r2=219934&view=diff
> ==============================================================================
> --- llvm/trunk/test/CodeGen/AArch64/sdivpow2.ll (original)
> +++ llvm/trunk/test/CodeGen/AArch64/sdivpow2.ll Thu Oct 16 11:41:15 2014
> @@ -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
> +}
> +
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>





More information about the llvm-commits mailing list