summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSam Parker <sam.parker@arm.com>2019-05-09 11:56:16 +0000
committerSam Parker <sam.parker@arm.com>2019-05-09 11:56:16 +0000
commitd7b650cc721f7dbb52cbfa0a50797e61990d7990 (patch)
tree720a9289b3b505e542787857e9387986898efe5b
parent933e305ed909fd93f9c2d7107b28e4ec2fea38ab (diff)
downloadbcm5719-llvm-d7b650cc721f7dbb52cbfa0a50797e61990d7990.tar.gz
bcm5719-llvm-d7b650cc721f7dbb52cbfa0a50797e61990d7990.zip
[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
-rw-r--r--llvm/lib/Target/ARM/ARMCodeGenPrepare.cpp22
-rw-r--r--llvm/test/CodeGen/ARM/CGP/arm-cgp-casts.ll44
-rw-r--r--llvm/test/CodeGen/ARM/CGP/arm-cgp-signed.ll25
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
+}
OpenPOWER on IntegriCloud