[llvm] r217980 - [FastISel][AArch64] Simplify mul to shift when possible.

Chad Rosier mcrosier at codeaurora.org
Mon Sep 22 12:00:15 PDT 2014


Juergen,
I'm seeing an ICE right about the time this landed.  Can you give the
following test case a try?

target triple = "aarch64--linux-gnu"

define void @foo() {
entry:
  br i1 undef, label %cond.true, label %cond.false

cond.true:                                        ; preds = %entry
  %conv80 = zext i1 undef to i32
  %mul = mul nsw i32 %conv80, 2
  store i32 %mul, i32* undef, align 4
  unreachable

cond.false:                                       ; preds = %entry
  unreachable
}

 Chad

> Author: ributzka
> Date: Wed Sep 17 15:35:41 2014
> New Revision: 217980
>
> URL: http://llvm.org/viewvc/llvm-project?rev=217980&view=rev
> Log:
> [FastISel][AArch64] Simplify mul to shift when possible.
>
> This is related to rdar://problem/18369687.
>
> Modified:
>     llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp
>     llvm/trunk/test/CodeGen/AArch64/fast-isel-mul.ll
>
> Modified: llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp?rev=217980&r1=217979&r2=217980&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp (original)
> +++ llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp Wed Sep 17 15:35:41
> 2014
> @@ -3749,15 +3749,54 @@ bool AArch64FastISel::selectRem(const In
>  }
>
>  bool AArch64FastISel::selectMul(const Instruction *I) {
> -  EVT SrcEVT = TLI.getValueType(I->getOperand(0)->getType(), true);
> -  if (!SrcEVT.isSimple())
> +  MVT VT;
> +  if (!isTypeSupported(I->getType(), VT, /*IsVectorAllowed=*/true))
>      return false;
> -  MVT SrcVT = SrcEVT.getSimpleVT();
>
> -  // Must be simple value type.  Don't handle vectors.
> -  if (SrcVT != MVT::i64 && SrcVT != MVT::i32 && SrcVT != MVT::i16 &&
> -      SrcVT != MVT::i8)
> -    return false;
> +  if (VT.isVector())
> +    return selectBinaryOp(I, ISD::MUL);
> +
> +  const Value *Src0 = I->getOperand(0);
> +  const Value *Src1 = I->getOperand(1);
> +  if (const auto *C = dyn_cast<ConstantInt>(Src0))
> +    if (C->getValue().isPowerOf2())
> +      std::swap(Src0, Src1);
> +
> +  // Try to simplify to a shift instruction.
> +  if (const auto *C = dyn_cast<ConstantInt>(Src1))
> +    if (C->getValue().isPowerOf2()) {
> +      uint64_t ShiftVal = C->getValue().logBase2();
> +      MVT SrcVT = VT;
> +      bool IsZExt = true;
> +      if (const auto *ZExt = dyn_cast<ZExtInst>(Src0)) {
> +        MVT VT;
> +        if (isValueAvailable(ZExt) && isTypeSupported(ZExt->getSrcTy(),
> VT)) {
> +          SrcVT = VT;
> +          IsZExt = true;
> +          Src0 = ZExt->getOperand(0);
> +        }
> +      } else if (const auto *SExt = dyn_cast<SExtInst>(Src0)) {
> +        MVT VT;
> +        if (isValueAvailable(SExt) && isTypeSupported(SExt->getSrcTy(),
> VT)) {
> +          SrcVT = VT;
> +          IsZExt = false;
> +          Src0 = SExt->getOperand(0);
> +        }
> +      }
> +
> +      unsigned Src0Reg = getRegForValue(Src0);
> +      if (!Src0Reg)
> +        return false;
> +      bool Src0IsKill = hasTrivialKill(Src0);
> +
> +      unsigned ResultReg =
> +          emitLSL_ri(VT, SrcVT, Src0Reg, Src0IsKill, ShiftVal, IsZExt);
> +
> +      if (ResultReg) {
> +        updateValueMap(I, ResultReg);
> +        return true;
> +      }
> +    }
>
>    unsigned Src0Reg = getRegForValue(I->getOperand(0));
>    if (!Src0Reg)
> @@ -3769,8 +3808,7 @@ bool AArch64FastISel::selectMul(const In
>      return false;
>    bool Src1IsKill = hasTrivialKill(I->getOperand(1));
>
> -  unsigned ResultReg =
> -      emitMul_rr(SrcVT, Src0Reg, Src0IsKill, Src1Reg, Src1IsKill);
> +  unsigned ResultReg = emitMul_rr(VT, Src0Reg, Src0IsKill, Src1Reg,
> Src1IsKill);
>
>    if (!ResultReg)
>      return false;
> @@ -3950,9 +3988,7 @@ bool AArch64FastISel::fastSelectInstruct
>    case Instruction::Sub:
>      return selectAddSub(I);
>    case Instruction::Mul:
> -    if (!selectBinaryOp(I, ISD::MUL))
> -      return selectMul(I);
> -    return true;
> +    return selectMul(I);
>    case Instruction::SRem:
>      if (!selectBinaryOp(I, ISD::SREM))
>        return selectRem(I, ISD::SREM);
>
> Modified: llvm/trunk/test/CodeGen/AArch64/fast-isel-mul.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/fast-isel-mul.ll?rev=217980&r1=217979&r2=217980&view=diff
> ==============================================================================
> --- llvm/trunk/test/CodeGen/AArch64/fast-isel-mul.ll (original)
> +++ llvm/trunk/test/CodeGen/AArch64/fast-isel-mul.ll Wed Sep 17 15:35:41
> 2014
> @@ -1,40 +1,44 @@
> -; RUN: llc -fast-isel -fast-isel-abort -verify-machineinstrs
> -mtriple=aarch64 < %s | FileCheck %s
> +; RUN: llc -fast-isel -fast-isel-abort -verify-machineinstrs
> -mtriple=aarch64-apple-darwin < %s | FileCheck %s
>
> - at var8 = global i8 0
> - at var16 = global i16 0
> - at var32 = global i32 0
> - at var64 = global i64 0
> -
> -define void @test_mul8(i8 %lhs, i8 %rhs) {
> +define zeroext i8 @test_mul8(i8 %lhs, i8 %rhs) {
>  ; CHECK-LABEL: test_mul8:
> -; CHECK: mul {{w[0-9]+}}, w0, w1
> -;  %lhs = load i8* @var8
> -;  %rhs = load i8* @var8
> -  %prod = mul i8 %lhs, %rhs
> -  store i8 %prod, i8* @var8
> -  ret void
> +; CHECK:       mul {{w[0-9]+}}, w0, w1
> +  %1 = mul i8 %lhs, %rhs
> +  ret i8 %1
>  }
>
> -define void @test_mul16(i16 %lhs, i16 %rhs) {
> +define zeroext i16 @test_mul16(i16 %lhs, i16 %rhs) {
>  ; CHECK-LABEL: test_mul16:
> -; CHECK: mul {{w[0-9]+}}, w0, w1
> -  %prod = mul i16 %lhs, %rhs
> -  store i16 %prod, i16* @var16
> -  ret void
> +; CHECK:       mul {{w[0-9]+}}, w0, w1
> +  %1 = mul i16 %lhs, %rhs
> +  ret i16 %1
>  }
>
> -define void @test_mul32(i32 %lhs, i32 %rhs) {
> +define i32 @test_mul32(i32 %lhs, i32 %rhs) {
>  ; CHECK-LABEL: test_mul32:
> -; CHECK: mul {{w[0-9]+}}, w0, w1
> -  %prod = mul i32 %lhs, %rhs
> -  store i32 %prod, i32* @var32
> -  ret void
> +; CHECK:       mul {{w[0-9]+}}, w0, w1
> +  %1 = mul i32 %lhs, %rhs
> +  ret i32 %1
>  }
>
> -define void @test_mul64(i64 %lhs, i64 %rhs) {
> +define i64 @test_mul64(i64 %lhs, i64 %rhs) {
>  ; CHECK-LABEL: test_mul64:
> -; CHECK: mul {{x[0-9]+}}, x0, x1
> -  %prod = mul i64 %lhs, %rhs
> -  store i64 %prod, i64* @var64
> -  ret void
> +; CHECK:       mul {{x[0-9]+}}, x0, x1
> +  %1 = mul i64 %lhs, %rhs
> +  ret i64 %1
> +}
> +
> +define i32 @test_mul2shift_i32(i32 %a) {
> +; CHECK-LABEL: test_mul2shift_i32:
> +; CHECK:       lsl {{w[0-9]+}}, w0, #2
> +  %1 = mul i32 %a, 4
> +  ret i32 %1
>  }
> +
> +define i64 @test_mul2shift_i64(i64 %a) {
> +; CHECK-LABEL: test_mul2shift_i64:
> +; CHECK:       lsl {{x[0-9]+}}, x0, #3
> +  %1 = mul i64 %a, 8
> +  ret i64 %1
> +}
> +
>
>
> _______________________________________________
> 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