forked from OSchip/llvm-project
[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: 208501
This commit is contained in:
parent
60cae1ba49
commit
c4c6c87666
|
@ -370,6 +370,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;
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
; 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 }
|
||||
|
Loading…
Reference in New Issue