From 0008934906149356834b1a2490a8beb889ef3770 Mon Sep 17 00:00:00 2001 From: Sam Parker Date: Thu, 9 May 2019 11:56:16 +0000 Subject: [PATCH] [ARM][CGP] Guard against signext args and sitofp Add an Argument that has the SExtAttr attached, as well as SIToFP instructions, as values that generate sign bits. SIToFP doesn't strictly do this and could be treated as a sink to be sign-extended. Differential Revision: https://reviews.llvm.org/D61381 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@360331 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMCodeGenPrepare.cpp | 22 +++++++++-------- test/CodeGen/ARM/CGP/arm-cgp-casts.ll | 44 +++++++++++++++++++++++++++++++++- test/CodeGen/ARM/CGP/arm-cgp-signed.ll | 25 +++++++++++++++++++ 3 files changed, 80 insertions(+), 11 deletions(-) diff --git a/lib/Target/ARM/ARMCodeGenPrepare.cpp b/lib/Target/ARM/ARMCodeGenPrepare.cpp index b59f05d7112..93a715aa194 100644 --- a/lib/Target/ARM/ARMCodeGenPrepare.cpp +++ b/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(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 @@ static bool isPromotedResultSafe(Value *V) { if (!isa(V)) return true; - if (generateSignBits(V)) + if (GenerateSignBits(V)) return false; return !isa(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(V) || isa(V)) return true; @@ -849,9 +858,6 @@ bool ARMCodeGenPrepare::isSupportedValue(Value *V) { 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 @@ 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/test/CodeGen/ARM/CGP/arm-cgp-casts.ll b/test/CodeGen/ARM/CGP/arm-cgp-casts.ll index f0f444aed04..e269aacad28 100644 --- a/test/CodeGen/ARM/CGP/arm-cgp-casts.ll +++ b/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/test/CodeGen/ARM/CGP/arm-cgp-signed.ll b/test/CodeGen/ARM/CGP/arm-cgp-signed.ll index 7494b57f425..44f3829c6b4 100644 --- a/test/CodeGen/ARM/CGP/arm-cgp-signed.ll +++ b/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 +} -- 2.11.0