diff options
-rw-r--r-- | llvm/lib/Target/ARM/ARMCodeGenPrepare.cpp | 22 | ||||
-rw-r--r-- | llvm/test/CodeGen/ARM/CGP/arm-cgp-casts.ll | 44 | ||||
-rw-r--r-- | llvm/test/CodeGen/ARM/CGP/arm-cgp-signed.ll | 25 |
3 files changed, 80 insertions, 11 deletions
diff --git a/llvm/lib/Target/ARM/ARMCodeGenPrepare.cpp b/llvm/lib/Target/ARM/ARMCodeGenPrepare.cpp index b59f05d7112..93a715aa194 100644 --- a/llvm/lib/Target/ARM/ARMCodeGenPrepare.cpp +++ b/llvm/lib/Target/ARM/ARMCodeGenPrepare.cpp @@ -175,13 +175,17 @@ public: } -static bool generateSignBits(Value *V) { +static bool GenerateSignBits(Value *V) { + if (auto *Arg = dyn_cast<Argument>(V)) + return Arg->hasSExtAttr(); + if (!isa<Instruction>(V)) return false; unsigned Opc = cast<Instruction>(V)->getOpcode(); return Opc == Instruction::AShr || Opc == Instruction::SDiv || - Opc == Instruction::SRem; + Opc == Instruction::SRem || Opc == Instruction::SExt || + Opc == Instruction::SIToFP; } static bool EqualTypeSize(Value *V) { @@ -414,7 +418,7 @@ static bool isPromotedResultSafe(Value *V) { if (!isa<Instruction>(V)) return true; - if (generateSignBits(V)) + if (GenerateSignBits(V)) return false; return !isa<OverflowingBinaryOperator>(V); @@ -833,6 +837,11 @@ bool ARMCodeGenPrepare::isSupportedValue(Value *V) { return EqualTypeSize(I->getOperand(0)); } + if (GenerateSignBits(V)) { + LLVM_DEBUG(dbgs() << "ARM CGP: No, instruction can generate sign bits.\n"); + return false; + } + // Memory instructions if (isa<StoreInst>(V) || isa<GetElementPtrInst>(V)) return true; @@ -849,9 +858,6 @@ bool ARMCodeGenPrepare::isSupportedValue(Value *V) { isa<LoadInst>(V)) return isSupportedType(V); - if (isa<SExtInst>(V)) - return false; - if (auto *Cast = dyn_cast<CastInst>(V)) return isSupportedType(Cast) || isSupportedType(Cast->getOperand(0)); @@ -868,10 +874,6 @@ bool ARMCodeGenPrepare::isSupportedValue(Value *V) { if (!isSupportedType(V)) return false; - if (generateSignBits(V)) { - LLVM_DEBUG(dbgs() << "ARM CGP: No, instruction can generate sign bits.\n"); - return false; - } return true; } diff --git a/llvm/test/CodeGen/ARM/CGP/arm-cgp-casts.ll b/llvm/test/CodeGen/ARM/CGP/arm-cgp-casts.ll index f0f444aed04..e269aacad28 100644 --- a/llvm/test/CodeGen/ARM/CGP/arm-cgp-casts.ll +++ b/llvm/test/CodeGen/ARM/CGP/arm-cgp-casts.ll @@ -1,6 +1,6 @@ ; RUN: llc -mtriple=thumbv8.main -mcpu=cortex-m33 %s -arm-disable-cgp=false -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NODSP ; RUN: llc -mtriple=thumbv7-linux-android %s -arm-disable-cgp=false -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NODSP -; RUN: llc -mtriple=thumbv7em %s -arm-disable-cgp=false -arm-enable-scalar-dsp=true -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-DSP +; RUN: llc -mtriple=thumbv7em -mcpu=cortex-m7 %s -arm-disable-cgp=false -arm-enable-scalar-dsp=true -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-DSP ; RUN: llc -mtriple=thumbv8 %s -arm-disable-cgp=false -arm-enable-scalar-dsp=true -arm-enable-scalar-dsp-imms=true -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-DSP-IMM ; Transform will fail because the trunc is not a sink. @@ -643,3 +643,45 @@ cond.end: %cond = phi i32 [ %phitmp, %cond.false ], [ 0, %entry ] ret i32 %cond } + +; CHECK-LABEL: test_i8_sitofp +; CHECK: uxtb [[UXT:r[0-9]+]], r1 +; CHECK: sxtb [[SXT:r[0-9]+]], r1 +; CHECK: vmov [[VMOV:s[0-9]+]], [[SXT]] +; CHECK: vcvt.f32.s32 [[CVT:s[0-9]+]], [[VMOV]] +define float @test_i8_sitofp(i8* %ptr, i8 %arg) { +entry: + %0 = load i8, i8* %ptr, align 1 + %cmp = icmp eq i8 %0, %arg + br i1 %cmp, label %exit, label %if.end + +if.end: + %conv = sitofp i8 %arg to float + %div = fdiv float %conv, 2.000000e+01 + br label %exit + +exit: + %res = phi float [ 0.0, %entry ], [ %div, %if.end ] + ret float %res +} + +; CHECK-LABEL: test_i16_sitofp +; CHECK: uxth [[UXT:r[0-9]+]], r1 +; CHECK: sxth [[SXT:r[0-9]+]], r1 +; CHECK: vmov [[VMOV:s[0-9]+]], [[SXT]] +; CHECK: vcvt.f32.s32 [[CVT:s[0-9]+]], [[VMOV]] +define float @test_i16_sitofp(i16* %ptr, i16 %arg) { +entry: + %0 = load i16, i16* %ptr, align 1 + %cmp = icmp eq i16 %0, %arg + br i1 %cmp, label %exit, label %if.end + +if.end: + %conv = sitofp i16 %arg to float + %div = fdiv float %conv, 2.000000e+01 + br label %exit + +exit: + %res = phi float [ 0.0, %entry ], [ %div, %if.end ] + ret float %res +} diff --git a/llvm/test/CodeGen/ARM/CGP/arm-cgp-signed.ll b/llvm/test/CodeGen/ARM/CGP/arm-cgp-signed.ll index 7494b57f425..44f3829c6b4 100644 --- a/llvm/test/CodeGen/ARM/CGP/arm-cgp-signed.ll +++ b/llvm/test/CodeGen/ARM/CGP/arm-cgp-signed.ll @@ -43,3 +43,28 @@ define i16 @test_srem(i16 zeroext %arg) { ret i16 %conv } +; CHECK-LABEL: test_signext_b +; CHECK: ldrb [[LDR:r[0-9]+]], [r0] +; CHECK: sxtb [[SXT:r[0-9]+]], [[LDR]] +; CHECK: cm{{.*}} [[SXT]] +define i32 @test_signext_b(i8* %ptr, i8 signext %arg) { +entry: + %0 = load i8, i8* %ptr, align 1 + %1 = add nuw nsw i8 %0, %arg + %cmp = icmp ult i8 %1, 128 + %res = select i1 %cmp, i32 42, i32 20894 + ret i32 %res +} + +; CHECK-LABEL: test_signext_h +; CHECK: ldrh [[LDR:r[0-9]+]], [r0] +; CHECK: sxth [[SXT:r[0-9]+]], [[LDR]] +; CHECK: cm{{.*}} [[SXT]] +define i32 @test_signext_h(i16* %ptr, i16 signext %arg) { +entry: + %0 = load i16, i16* %ptr, align 1 + %1 = add nuw nsw i16 %0, %arg + %cmp = icmp ult i16 %1, 32768 + %res = select i1 %cmp, i32 42, i32 20894 + ret i32 %res +} |