aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm/patches/patch-25-llvm-r224890-ppc-ctr-tls-loop.diff
diff options
context:
space:
mode:
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.diff95
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 000000000000..aeb81f228961
--- /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
++}