diff options
| author | Hal Finkel <hfinkel@anl.gov> | 2013-05-18 09:20:39 +0000 |
|---|---|---|
| committer | Hal Finkel <hfinkel@anl.gov> | 2013-05-18 09:20:39 +0000 |
| commit | 2f474f0e8a53145f585cf040968bde09e13c613d (patch) | |
| tree | 14ad5f9dcde007f4977710bca0b0c7cf853b9724 /llvm | |
| parent | fd2639f784bb7b5e7907485a4e207b41e3b6523e (diff) | |
| download | bcm5719-llvm-2f474f0e8a53145f585cf040968bde09e13c613d.tar.gz bcm5719-llvm-2f474f0e8a53145f585cf040968bde09e13c613d.zip | |
Check InlineAsm clobbers in PPCCTRLoops
We don't need to reject all inline asm as using the counter register (most does
not). Only those that explicitly clobber the counter register need to prevent
the transformation.
llvm-svn: 182191
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/Target/PowerPC/PPCCTRLoops.cpp | 15 | ||||
| -rw-r--r-- | llvm/test/CodeGen/PowerPC/ctrloop-asm.ll | 38 |
2 files changed, 53 insertions, 0 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCCTRLoops.cpp b/llvm/lib/Target/PowerPC/PPCCTRLoops.cpp index 5d001fc0725..e8760dedea4 100644 --- a/llvm/lib/Target/PowerPC/PPCCTRLoops.cpp +++ b/llvm/lib/Target/PowerPC/PPCCTRLoops.cpp @@ -33,6 +33,7 @@ #include "llvm/Analysis/ScalarEvolutionExpander.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/InlineAsm.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/Module.h" @@ -148,6 +149,20 @@ bool PPCCTRLoops::mightUseCTR(const Triple &TT, BasicBlock *BB) { for (BasicBlock::iterator J = BB->begin(), JE = BB->end(); J != JE; ++J) { if (CallInst *CI = dyn_cast<CallInst>(J)) { + if (InlineAsm *IA = dyn_cast<InlineAsm>(CI->getCalledValue())) { + // Inline ASM is okay, unless it clobbers the ctr register. + InlineAsm::ConstraintInfoVector CIV = IA->ParseConstraints(); + for (unsigned i = 0, ie = CIV.size(); i < ie; ++i) { + InlineAsm::ConstraintInfo &C = CIV[i]; + if (C.Type != InlineAsm::isInput) + for (unsigned j = 0, je = C.Codes.size(); j < je; ++j) + if (StringRef(C.Codes[j]).equals_lower("{ctr}")) + return true; + } + + continue; + } + if (!TM) return true; const TargetLowering *TLI = TM->getTargetLowering(); diff --git a/llvm/test/CodeGen/PowerPC/ctrloop-asm.ll b/llvm/test/CodeGen/PowerPC/ctrloop-asm.ll new file mode 100644 index 00000000000..28afbf2babc --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/ctrloop-asm.ll @@ -0,0 +1,38 @@ +target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32:64" +target triple = "powerpc64-unknown-freebsd10.0" +; RUN: llc < %s -march=ppc64 | FileCheck %s + +define void @test1(i32 %c) nounwind { +entry: + br label %for.body + +for.body: ; preds = %for.body, %entry + %i.01 = phi i32 [ 0, %entry ], [ %inc, %for.body ] + call void asm sideeffect "", "~{r5}"() nounwind + %inc = add nsw i32 %i.01, 1 + %exitcond = icmp eq i32 %inc, 2048 + br i1 %exitcond, label %for.end, label %for.body + +for.end: ; preds = %for.body + ret void +; CHECK: @test1 +; CHECK: mtctr +} + +define void @test2(i32 %c) nounwind { +entry: + br label %for.body + +for.body: ; preds = %for.body, %entry + %i.01 = phi i32 [ 0, %entry ], [ %inc, %for.body ] + call void asm sideeffect "", "~{ctr}"() nounwind + %inc = add nsw i32 %i.01, 1 + %exitcond = icmp eq i32 %inc, 2048 + br i1 %exitcond, label %for.end, label %for.body + +for.end: ; preds = %for.body + ret void +; CHECK: @test2 +; CHECK-NOT: mtctr +} + |

