[PowerPC] Disable CTR loops optimization for soft float operations
authorPetar Jovanovic <petar.jovanovic@imgtec.com>
Thu, 17 Mar 2016 17:11:33 +0000 (17:11 +0000)
committerPetar Jovanovic <petar.jovanovic@imgtec.com>
Thu, 17 Mar 2016 17:11:33 +0000 (17:11 +0000)
This patch prevents CTR loops optimization when using soft float operations
inside loop body. Soft float operations use function calls, but function
calls are not allowed inside CTR optimized loops.

Patch by Aleksandar Beserminji.

Differential Revision: http://reviews.llvm.org/D17600

llvm-svn: 263727

llvm/lib/Target/PowerPC/PPCCTRLoops.cpp
llvm/test/CodeGen/PowerPC/ctrloops-softfloat.ll [new file with mode: 0644]

index b6ac4d5..b0a3e93 100644 (file)
@@ -422,6 +422,25 @@ bool PPCCTRLoops::mightUseCTR(const Triple &TT, BasicBlock *BB) {
       if (SI->getNumCases() + 1 >= (unsigned)TLI->getMinimumJumpTableEntries())
         return true;
     }
+
+    if (TM->getSubtargetImpl(*BB->getParent())->getTargetLowering()->useSoftFloat()) {
+      switch(J->getOpcode()) {
+      case Instruction::FAdd:
+      case Instruction::FSub:
+      case Instruction::FMul:
+      case Instruction::FDiv:
+      case Instruction::FRem:
+      case Instruction::FPTrunc:
+      case Instruction::FPExt:
+      case Instruction::FPToUI:
+      case Instruction::FPToSI:
+      case Instruction::UIToFP:
+      case Instruction::SIToFP:
+      case Instruction::FCmp:
+        return true;
+      }
+    }
+
     for (Value *Operand : J->operands())
       if (memAddrUsesCTR(TM, Operand))
         return true;
diff --git a/llvm/test/CodeGen/PowerPC/ctrloops-softfloat.ll b/llvm/test/CodeGen/PowerPC/ctrloops-softfloat.ll
new file mode 100644 (file)
index 0000000..037bfda
--- /dev/null
@@ -0,0 +1,129 @@
+; RUN: llc -mtriple=powerpc-unknown-linux-gnu -O1 < %s | FileCheck %s
+
+; double x, y;
+; 
+; void foo1()
+; {
+;   x = y = 1.1;
+;   for (int i = 0; i < 175; i++)
+;     y = x + y;    
+; }
+; void foo2()
+; {
+;   x = y = 1.1;
+;   for (int i = 0; i < 175; i++)
+;     y = x - y;    
+; }
+; void foo3()
+; {
+;   x = y = 1.1;
+;   for (int i = 0; i < 175; i++)
+;     y = x * y;    
+; }
+; void foo4()
+; {
+;   x = y = 1.1;
+;   for (int i = 0; i < 175; i++)
+;     y = x / y;    
+; }
+
+target datalayout = "E-m:e-p:32:32-i64:64-n32"
+target triple = "powerpc-buildroot-linux-gnu"
+
+@y = common global double 0.000000e+00, align 8
+@x = common global double 0.000000e+00, align 8
+
+define void @foo1() #0 {
+  store double 1.100000e+00, double* @y, align 8
+  store double 1.100000e+00, double* @x, align 8
+  br label %2
+
+; <label>:1                                       ; preds = %2
+  %.lcssa = phi double [ %4, %2 ]
+  store double %.lcssa, double* @y, align 8
+  ret void
+
+; <label>:2                                       ; preds = %2, %0
+  %3 = phi double [ 1.100000e+00, %0 ], [ %4, %2 ]
+  %i.01 = phi i32 [ 0, %0 ], [ %5, %2 ]
+  %4 = fadd double %3, 1.100000e+00
+  %5 = add nuw nsw i32 %i.01, 1
+  %exitcond = icmp eq i32 %5, 75
+  br i1 %exitcond, label %1, label %2
+  ; CHECK: bl __adddf3
+  ; CHECK: cmplwi
+  ; CHECK-NOT: li [[REG1:[0-9]+]], 175
+  ; CHECK-NOT: mtctr [[REG1]]
+}
+
+define void @foo2() #0 {
+  store double 1.100000e+00, double* @y, align 8
+  store double 1.100000e+00, double* @x, align 8
+  br label %2
+
+; <label>:1                                       ; preds = %2
+  %.lcssa = phi double [ %4, %2 ]
+  store double %.lcssa, double* @y, align 8
+  ret void
+
+; <label>:2                                       ; preds = %2, %0
+  %3 = phi double [ 1.100000e+00, %0 ], [ %4, %2 ]
+  %i.01 = phi i32 [ 0, %0 ], [ %5, %2 ]
+  %4 = fsub double 1.100000e+00, %3
+  %5 = add nuw nsw i32 %i.01, 1
+  %exitcond = icmp eq i32 %5, 75
+  br i1 %exitcond, label %1, label %2
+  ; CHECK: bl __subdf3
+  ; CHECK: cmplwi
+  ; CHECK-NOT: li [[REG1:[0-9]+]], 175
+  ; CHECK-NOT: mtctr [[REG1]]
+}
+
+define void @foo3() #0 {
+  store double 1.100000e+00, double* @y, align 8
+  store double 1.100000e+00, double* @x, align 8
+  br label %2
+
+; <label>:1                                       ; preds = %2
+  %.lcssa = phi double [ %4, %2 ]
+  store double %.lcssa, double* @y, align 8
+  ret void
+
+; <label>:2                                       ; preds = %2, %0
+  %3 = phi double [ 1.100000e+00, %0 ], [ %4, %2 ]
+  %i.01 = phi i32 [ 0, %0 ], [ %5, %2 ]
+  %4 = fmul double %3, 1.100000e+00
+  %5 = add nuw nsw i32 %i.01, 1
+  %exitcond = icmp eq i32 %5, 75
+  br i1 %exitcond, label %1, label %2
+  ; CHECK: bl __muldf3
+  ; CHECK: cmplwi
+  ; CHECK-NOT: li [[REG1:[0-9]+]], 175
+  ; CHECK-NOT: mtctr [[REG1]]
+}
+
+define void @foo4() #0 {
+  store double 1.100000e+00, double* @y, align 8
+  store double 1.100000e+00, double* @x, align 8
+  br label %2
+
+; <label>:1                                       ; preds = %2
+  %.lcssa = phi double [ %4, %2 ]
+  store double %.lcssa, double* @y, align 8
+  ret void
+
+; <label>:2                                       ; preds = %2, %0
+  %3 = phi double [ 1.100000e+00, %0 ], [ %4, %2 ]
+  %i.01 = phi i32 [ 0, %0 ], [ %5, %2 ]
+  %4 = fdiv double 1.100000e+00, %3
+  %5 = add nuw nsw i32 %i.01, 1
+  %exitcond = icmp eq i32 %5, 75
+  br i1 %exitcond, label %1, label %2
+  ; CHECK: bl __divdf3
+  ; CHECK: cmplwi
+  ; CHECK-NOT: li [[REG1:[0-9]+]], 175
+  ; CHECK-NOT: mtctr [[REG1]]
+}
+
+attributes #0 = { "use-soft-float"="true" }
+