mirror of
https://git.hardenedbsd.org/hardenedbsd/HardenedBSD.git
synced 2024-12-23 18:14:56 +01:00
96 lines
3.0 KiB
Diff
96 lines
3.0 KiB
Diff
|
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
|
||
|
+}
|