OSDN Git Service

[ARM][CGP] Guard against signext args and sitofp
authorSam Parker <sam.parker@arm.com>
Thu, 9 May 2019 11:56:16 +0000 (11:56 +0000)
committerSam Parker <sam.parker@arm.com>
Thu, 9 May 2019 11:56:16 +0000 (11:56 +0000)
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
test/CodeGen/ARM/CGP/arm-cgp-casts.ll
test/CodeGen/ARM/CGP/arm-cgp-signed.ll

index b59f05d..93a715a 100644 (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;
 }
 
index f0f444a..e269aac 100644 (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
+}
index 7494b57..44f3829 100644 (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
+}