OSDN Git Service

[Hexagon] Generate post-increment for floating point types
authorBrendon Cahoon <bcahoon@codeaurora.org>
Fri, 18 May 2018 18:14:44 +0000 (18:14 +0000)
committerBrendon Cahoon <bcahoon@codeaurora.org>
Fri, 18 May 2018 18:14:44 +0000 (18:14 +0000)
The code that generates post-increments for Hexagon considered
integer values only. This patch adds support to generate them for
floating point values, f32 and f64.

Differential Revision: https://reviews.llvm.org/D47036

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@332748 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/Hexagon/HexagonISelDAGToDAG.cpp
lib/Target/Hexagon/HexagonISelLowering.cpp
lib/Target/Hexagon/HexagonInstrInfo.cpp
test/CodeGen/Hexagon/postinc-float.ll [new file with mode: 0644]
test/CodeGen/Hexagon/swp-memrefs-epilog.ll

index 20e8dcd..0d0b351 100644 (file)
@@ -93,11 +93,13 @@ void HexagonDAGToDAGISel::SelectIndexedLoad(LoadSDNode *LD, const SDLoc &dl) {
       Opcode = IsValidInc ? Hexagon::L2_loadrh_pi : Hexagon::L2_loadrh_io;
     break;
   case MVT::i32:
+  case MVT::f32:
   case MVT::v2i16:
   case MVT::v4i8:
     Opcode = IsValidInc ? Hexagon::L2_loadri_pi : Hexagon::L2_loadri_io;
     break;
   case MVT::i64:
+  case MVT::f64:
   case MVT::v2i32:
   case MVT::v4i16:
   case MVT::v8i8:
@@ -483,11 +485,13 @@ void HexagonDAGToDAGISel::SelectIndexedStore(StoreSDNode *ST, const SDLoc &dl) {
     Opcode = IsValidInc ? Hexagon::S2_storerh_pi : Hexagon::S2_storerh_io;
     break;
   case MVT::i32:
+  case MVT::f32:
   case MVT::v2i16:
   case MVT::v4i8:
     Opcode = IsValidInc ? Hexagon::S2_storeri_pi : Hexagon::S2_storeri_io;
     break;
   case MVT::i64:
+  case MVT::f64:
   case MVT::v2i32:
   case MVT::v4i16:
   case MVT::v8i8:
index ce42a9b..2b66099 100644 (file)
@@ -550,8 +550,9 @@ bool HexagonTargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op,
   if (!VT.isSimple())
     return false;
   bool IsLegalType = VT == MVT::i8 || VT == MVT::i16 || VT == MVT::i32 ||
-                     VT == MVT::i64 || VT == MVT::v2i16 || VT == MVT::v2i32 ||
-                     VT == MVT::v4i8 || VT == MVT::v4i16 || VT == MVT::v8i8 ||
+                     VT == MVT::i64 || VT == MVT::f32 || VT == MVT::f64 ||
+                     VT == MVT::v2i16 || VT == MVT::v2i32 || VT == MVT::v4i8 ||
+                     VT == MVT::v4i16 || VT == MVT::v8i8 ||
                      Subtarget.isHVXVectorType(VT.getSimpleVT());
   if (!IsLegalType)
     return false;
@@ -1579,8 +1580,8 @@ HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &TM,
 
   // Handling of indexed loads/stores: default is "expand".
   //
-  for (MVT VT : {MVT::i8, MVT::i16, MVT::i32, MVT::i64, MVT::v2i16,
-                 MVT::v2i32, MVT::v4i8, MVT::v4i16, MVT::v8i8}) {
+  for (MVT VT : {MVT::i8, MVT::i16, MVT::i32, MVT::i64, MVT::f32, MVT::f64,
+                 MVT::v2i16, MVT::v2i32, MVT::v4i8, MVT::v4i16, MVT::v8i8}) {
     setIndexedLoadAction(ISD::POST_INC, VT, Legal);
     setIndexedStoreAction(ISD::POST_INC, VT, Legal);
   }
index 34b07c6..0a38783 100644 (file)
@@ -2585,6 +2585,8 @@ bool HexagonInstrInfo::isValidAutoIncImm(const EVT VT, int Offset) const {
     case MVT::i16:
     case MVT::i32:
     case MVT::i64:
+    case MVT::f32:
+    case MVT::f64:
     case MVT::v2i16:
     case MVT::v2i32:
     case MVT::v4i8:
diff --git a/test/CodeGen/Hexagon/postinc-float.ll b/test/CodeGen/Hexagon/postinc-float.ll
new file mode 100644 (file)
index 0000000..55bf82d
--- /dev/null
@@ -0,0 +1,86 @@
+; RUN: llc -mtriple=hexagon-unknown-elf < %s | FileCheck %s
+
+; CHECK-LABEL: ldf
+; CHECK: memw(r{{[0-9]+}}++#4)
+; CHECK: memw(r{{[0-9]+}}++#4)
+define float @ldf(float* nocapture readonly %x, float* nocapture readonly %y) local_unnamed_addr #0 {
+entry:
+  br label %for.body
+
+for.body:
+  %arrayidx.phi = phi float* [ %x, %entry ], [ %arrayidx.inc, %for.body ]
+  %arrayidx1.phi = phi float* [ %y, %entry ], [ %arrayidx1.inc, %for.body ]
+  %i.09 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
+  %acc.08 = phi float [ 0.000000e+00, %entry ], [ %add, %for.body ]
+  %0 = load float, float* %arrayidx.phi, align 4
+  %1 = load float, float* %arrayidx1.phi, align 4
+  %mul = fmul contract float %0, %1
+  %add = fadd contract float %acc.08, %mul
+  %inc = add nuw nsw i32 %i.09, 1
+  %exitcond = icmp eq i32 %inc, 1024
+  %arrayidx.inc = getelementptr float, float* %arrayidx.phi, i32 1
+  %arrayidx1.inc = getelementptr float, float* %arrayidx1.phi, i32 1
+  br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+  ret float %add
+}
+
+; CHECK-LABEL: ldd
+; CHECK: memd(r{{[0-9]+}}++#8)
+; CHECK: memd(r{{[0-9]+}}++#8)
+define double @ldd(double* nocapture readonly %x, double* nocapture readonly %y) local_unnamed_addr #0 {
+entry:
+  br label %for.body
+
+for.body:
+  %arrayidx.phi = phi double* [ %x, %entry ], [ %arrayidx.inc, %for.body ]
+  %arrayidx1.phi = phi double* [ %y, %entry ], [ %arrayidx1.inc, %for.body ]
+  %i.09 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
+  %acc.08 = phi double [ 0.000000e+00, %entry ], [ %add, %for.body ]
+  %0 = load double, double* %arrayidx.phi, align 8
+  %1 = load double, double* %arrayidx1.phi, align 8
+  %mul = fmul contract double %0, %1
+  %add = fadd contract double %acc.08, %mul
+  %inc = add nuw nsw i32 %i.09, 1
+  %exitcond = icmp eq i32 %inc, 1024
+  %arrayidx.inc = getelementptr double, double* %arrayidx.phi, i32 1
+  %arrayidx1.inc = getelementptr double, double* %arrayidx1.phi, i32 1
+  br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+  ret double %add
+}
+
+; CHECK-LABEL: stf
+; CHECK: memw(r{{[0-9]+}}++#4)
+define double* @stf(float* returned %p) local_unnamed_addr #0 {
+entry:
+  br label %for.body
+
+for.body:
+  %arrayidx.phi = phi float* [ %arrayidx.inc, %for.body ], [ %p, %entry ]
+  %call = tail call float @foof() #2
+  store float %call, float* %arrayidx.phi, align 8
+  %arrayidx.inc = getelementptr float, float* %arrayidx.phi, i32 1
+  br label %for.body
+}
+
+declare float @foof() local_unnamed_addr #1
+
+; CHECK-LABEL: std
+; CHECK: memd(r{{[0-9]+}}++#8)
+define double* @std(double* returned %p) local_unnamed_addr #0 {
+entry:
+  br label %for.body
+
+for.body:
+  %arrayidx.phi = phi double* [ %arrayidx.inc, %for.body ], [ %p, %entry ]
+  %call = tail call double @food() #2
+  store double %call, double* %arrayidx.phi, align 8
+  %arrayidx.inc = getelementptr double, double* %arrayidx.phi, i32 1
+  br label %for.body
+}
+
+declare double @food() local_unnamed_addr #1
+
index ee01711..81f4d22 100644 (file)
@@ -10,8 +10,7 @@
 ; to r29+32. If the memoperands are updated incorrectly, these are swapped.
 
 ; CHECK: [[REG0:r([0-9]+)]] = add(r29,#24)
-; CHECK: [[REG1:r([0-9]+)]] = add([[REG0]],#4)
-; CHECK: memw([[REG1]]+#{{[0-9]}}) = r{{[0-9]+}}
+; CHECK: memw([[REG0]]++#4) = r{{[0-9]+}}
 ; CHECK: r{{[0-9]+}} = memw(r29+#{{[0-9]+}})
 
 %s.0 = type { %s.1 }