1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-02-01 05:01:59 +01:00

[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

llvm-svn: 360331
This commit is contained in:
Sam Parker 2019-05-09 11:56:16 +00:00
parent 8dedb06ab3
commit 4b49577509
3 changed files with 80 additions and 11 deletions

View File

@ -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;
}

View File

@ -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
}

View File

@ -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
}