diff options
Diffstat (limited to 'contrib/llvm/patches/patch-25-llvm-r224890-ppc-ctr-tls-loop.diff')
-rw-r--r-- | contrib/llvm/patches/patch-25-llvm-r224890-ppc-ctr-tls-loop.diff | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/contrib/llvm/patches/patch-25-llvm-r224890-ppc-ctr-tls-loop.diff b/contrib/llvm/patches/patch-25-llvm-r224890-ppc-ctr-tls-loop.diff new file mode 100644 index 0000000..aeb81f2 --- /dev/null +++ b/contrib/llvm/patches/patch-25-llvm-r224890-ppc-ctr-tls-loop.diff @@ -0,0 +1,95 @@ +Pull in r224890 from upstream llvm trunk (by David Majnemer): + + PowerPC: CTR shouldn't fire if a TLS call is in the loop + + Determining the address of a TLS variable results in a function call in + certain TLS models. This means that a simple ICmpInst might actually + result in invalidating the CTR register. + + In such cases, do not attempt to rely on the CTR register for loop + optimization purposes. + + This fixes PR22034. + + Differential Revision: http://reviews.llvm.org/D6786 + +This fixes a "Invalid PPC CTR loop" error when compiling parts of libc +for PowerPC-32. + +Introduced here: http://svnweb.freebsd.org/changeset/base/276324 + +Index: lib/Target/PowerPC/PPCCTRLoops.cpp +=================================================================== +--- lib/Target/PowerPC/PPCCTRLoops.cpp ++++ lib/Target/PowerPC/PPCCTRLoops.cpp +@@ -194,6 +194,21 @@ static bool isLargeIntegerTy(bool Is32Bit, Type *T + return false; + } + ++// Determining the address of a TLS variable results in a function call in ++// certain TLS models. ++static bool memAddrUsesCTR(const PPCTargetMachine *TM, ++ const llvm::Value *MemAddr) { ++ const auto *GV = dyn_cast<GlobalValue>(MemAddr); ++ if (!GV) ++ return false; ++ if (!GV->isThreadLocal()) ++ return false; ++ if (!TM) ++ return true; ++ TLSModel::Model Model = TM->getTLSModel(GV); ++ return Model == TLSModel::GeneralDynamic || Model == TLSModel::LocalDynamic; ++} ++ + bool PPCCTRLoops::mightUseCTR(const Triple &TT, BasicBlock *BB) { + for (BasicBlock::iterator J = BB->begin(), JE = BB->end(); + J != JE; ++J) { +@@ -390,6 +405,9 @@ bool PPCCTRLoops::mightUseCTR(const Triple &TT, Ba + SI->getNumCases()+1 >= (unsigned) TLI->getMinimumJumpTableEntries()) + return true; + } ++ for (Value *Operand : J->operands()) ++ if (memAddrUsesCTR(TM, Operand)) ++ return true; + } + + return false; +Index: test/CodeGen/PowerPC/ctrloops.ll +=================================================================== +--- test/CodeGen/PowerPC/ctrloops.ll ++++ test/CodeGen/PowerPC/ctrloops.ll +@@ -1,6 +1,6 @@ + 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 ++; RUN: llc < %s -march=ppc64 -relocation-model=pic | FileCheck %s + + @a = common global i32 0, align 4 + +@@ -73,3 +73,26 @@ for.end: + ; CHECK-NOT: cmplwi + ; CHECK: bdnz + } ++ ++@tls_var = external thread_local global i8 ++ ++define i32 @test4() { ++entry: ++ br label %for.body ++ ++for.body: ; preds = %for.body, %entry ++ %phi = phi i32 [ %dec, %for.body ], [ undef, %entry ] ++ %load = ptrtoint i8* @tls_var to i32 ++ %dec = add i32 %phi, -1 ++ %cmp = icmp sgt i32 %phi, 1 ++ br i1 %cmp, label %for.body, label %return ++ ++return: ; preds = %for.body ++ ret i32 %load ++; CHECK-LABEL: @test4 ++; CHECK-NOT: mtctr ++; CHECK: addi {{[0-9]+}} ++; CHECK: cmpwi ++; CHECK-NOT: bdnz ++; CHECK: bgt ++} |