Commit d6d85825 authored by Tom Stellard's avatar Tom Stellard
Browse files

Merging r208501:

------------------------------------------------------------------------
r208501 | hfinkel | 2014-05-11 12:23:29 -0400 (Sun, 11 May 2014) | 9 lines

[PowerPC] On PPC32, 128-bit shifts might be runtime calls

The counter-loops formation pass needs to know what operations might be
function calls (because they can't appear in counter-based loops). On PPC32,
128-bit shifts might be runtime calls (even though you can't use __int128 on
PPC32, it seems that SROA might form them).

Fixes PR19709.

------------------------------------------------------------------------

llvm-svn: 208916
parent 6bed7521
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -369,6 +369,14 @@ bool PPCCTRLoops::mightUseCTR(const Triple &TT, BasicBlock *BB) {
                J->getOpcode() == Instruction::URem ||
                J->getOpcode() == Instruction::SRem)) {
      return true;
    } else if (TT.isArch32Bit() &&
               isLargeIntegerTy(false, J->getType()->getScalarType()) &&
               (J->getOpcode() == Instruction::Shl ||
                J->getOpcode() == Instruction::AShr ||
                J->getOpcode() == Instruction::LShr)) {
      // Only on PPC32, for 128-bit integers (specifically not 64-bit
      // integers), these might be runtime calls.
      return true;
    } else if (isa<IndirectBrInst>(J) || isa<InvokeInst>(J)) {
      // On PowerPC, indirect jumps use the counter register.
      return true;
+72 −0
Original line number Diff line number Diff line
; RUN: llc < %s | FileCheck %s
target datalayout = "E-m:e-p:32:32-i128:64-n32"
target triple = "powerpc-ellcc-linux"

; Function Attrs: nounwind
define void @foo1(i128* %a, i128* readonly %b, i128* readonly %c) #0 {
entry:
  br label %for.body

for.body:                                         ; preds = %for.body, %entry
  %i.02 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
  %0 = load i128* %b, align 16
  %1 = load i128* %c, align 16
  %shl = shl i128 %0, %1
  store i128 %shl, i128* %a, align 16
  %inc = add nsw i32 %i.02, 1
  %exitcond = icmp eq i32 %inc, 2048
  br i1 %exitcond, label %for.end, label %for.body

for.end:                                          ; preds = %for.body
  ret void

; CHECK-LABEL: @foo1
; CHECK-NOT: mtctr
}

; Function Attrs: nounwind
define void @foo2(i128* %a, i128* readonly %b, i128* readonly %c) #0 {
entry:
  br label %for.body

for.body:                                         ; preds = %for.body, %entry
  %i.02 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
  %0 = load i128* %b, align 16
  %1 = load i128* %c, align 16
  %shl = ashr i128 %0, %1
  store i128 %shl, i128* %a, align 16
  %inc = add nsw i32 %i.02, 1
  %exitcond = icmp eq i32 %inc, 2048
  br i1 %exitcond, label %for.end, label %for.body

for.end:                                          ; preds = %for.body
  ret void

; CHECK-LABEL: @foo2
; CHECK-NOT: mtctr
}

; Function Attrs: nounwind
define void @foo3(i128* %a, i128* readonly %b, i128* readonly %c) #0 {
entry:
  br label %for.body

for.body:                                         ; preds = %for.body, %entry
  %i.02 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
  %0 = load i128* %b, align 16
  %1 = load i128* %c, align 16
  %shl = lshr i128 %0, %1
  store i128 %shl, i128* %a, align 16
  %inc = add nsw i32 %i.02, 1
  %exitcond = icmp eq i32 %inc, 2048
  br i1 %exitcond, label %for.end, label %for.body

for.end:                                          ; preds = %for.body
  ret void

; CHECK-LABEL: @foo3
; CHECK-NOT: mtctr
}

attributes #0 = { nounwind }