Index: lib/Target/ARM/ARMCodeGenPrepare.cpp =================================================================== --- lib/Target/ARM/ARMCodeGenPrepare.cpp +++ lib/Target/ARM/ARMCodeGenPrepare.cpp @@ -175,13 +175,17 @@ } -static bool generateSignBits(Value *V) { +static bool GenerateSignBits(Value *V) { + if (auto *Arg = dyn_cast(V)) + return Arg->hasSExtAttr(); + if (!isa(V)) return false; unsigned Opc = cast(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 @@ if (!isa(V)) return true; - if (generateSignBits(V)) + if (GenerateSignBits(V)) return false; return !isa(V); @@ -833,6 +837,11 @@ 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(V) || isa(V)) return true; @@ -849,9 +858,6 @@ isa(V)) return isSupportedType(V); - if (isa(V)) - return false; - if (auto *Cast = dyn_cast(V)) return isSupportedType(Cast) || isSupportedType(Cast->getOperand(0)); @@ -868,10 +874,6 @@ if (!isSupportedType(V)) return false; - if (generateSignBits(V)) { - LLVM_DEBUG(dbgs() << "ARM CGP: No, instruction can generate sign bits.\n"); - return false; - } return true; } Index: test/CodeGen/ARM/CGP/arm-cgp-casts.ll =================================================================== --- test/CodeGen/ARM/CGP/arm-cgp-casts.ll +++ 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 = 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 +} Index: test/CodeGen/ARM/CGP/arm-cgp-signed.ll =================================================================== --- test/CodeGen/ARM/CGP/arm-cgp-signed.ll +++ test/CodeGen/ARM/CGP/arm-cgp-signed.ll @@ -43,3 +43,28 @@ 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 +}