Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[power] reenable partword atomics #18639

Merged
merged 1 commit into from
Sep 23, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions deps/llvm.mk
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,7 @@ else ifeq ($(LLVM_VER_SHORT),3.9)
# fix lowering for atomics on ppc
$(eval $(call LLVM_PATCH,llvm-rL279933-ppc-atomicrmw-lowering)) # Remove for 4.0
$(eval $(call LLVM_PATCH,llvm-PR22923)) # Remove for 4.0
$(eval $(call LLVM_PATCH,llvm-r282182)) # Remove for 4.0
endif # LLVM_VER

ifeq ($(LLVM_VER),3.7.1)
Expand Down
116 changes: 116 additions & 0 deletions deps/patches/llvm-r282182.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
From f2f9e2bcc5e9dd33c5c74e1aa615bf9f28f7d316 Mon Sep 17 00:00:00 2001
From: Nemanja Ivanovic <nemanja.i.ibm@gmail.com>
Date: Thu, 22 Sep 2016 19:06:38 +0000
Subject: [PATCH] [PowerPC] Sign extend sub-word values for atomic comparisons

Atomic comparison instructions use the sub-word load instruction on
Power8 and up but the value is not sign extended prior to the signed word
compare instruction. This patch adds that sign extension.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@282182 91177308-0d34-0410-b5e6-96231b3b80d8
---
lib/Target/PowerPC/PPCISelLowering.cpp | 13 ++++++-
test/CodeGen/PowerPC/pr30451.ll | 69 ++++++++++++++++++++++++++++++++++
2 files changed, 80 insertions(+), 2 deletions(-)
create mode 100644 test/CodeGen/PowerPC/pr30451.ll

diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp
index 1d9181b..c414a15 100644
--- a/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -8507,8 +8507,17 @@ PPCTargetLowering::EmitAtomicBinary(MachineInstr &MI, MachineBasicBlock *BB,
if (BinOpcode)
BuildMI(BB, dl, TII->get(BinOpcode), TmpReg).addReg(incr).addReg(dest);
if (CmpOpcode) {
- BuildMI(BB, dl, TII->get(CmpOpcode), PPC::CR0)
- .addReg(incr).addReg(dest);
+ // Signed comparisons of byte or halfword values must be sign-extended.
+ if (CmpOpcode == PPC::CMPW && AtomicSize < 4) {
+ unsigned ExtReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
+ BuildMI(BB, dl, TII->get(AtomicSize == 1 ? PPC::EXTSB : PPC::EXTSH),
+ ExtReg).addReg(dest);
+ BuildMI(BB, dl, TII->get(CmpOpcode), PPC::CR0)
+ .addReg(incr).addReg(ExtReg);
+ } else
+ BuildMI(BB, dl, TII->get(CmpOpcode), PPC::CR0)
+ .addReg(incr).addReg(dest);
+
BuildMI(BB, dl, TII->get(PPC::BCC))
.addImm(CmpPred).addReg(PPC::CR0).addMBB(exitMBB);
BB->addSuccessor(loop2MBB);
diff --git a/test/CodeGen/PowerPC/pr30451.ll b/test/CodeGen/PowerPC/pr30451.ll
new file mode 100644
index 0000000..9305534
--- /dev/null
+++ b/test/CodeGen/PowerPC/pr30451.ll
@@ -0,0 +1,69 @@
+; RUN: llc < %s -mcpu=pwr8 -mtriple=powerpc64le-unknown-unknown | FileCheck %s
+define i8 @atomic_min_i8() {
+ top:
+ %0 = alloca i8, align 2
+ %1 = bitcast i8* %0 to i8*
+ call void @llvm.lifetime.start(i64 2, i8* %1)
+ store i8 -1, i8* %0, align 2
+ %2 = atomicrmw min i8* %0, i8 0 acq_rel
+ %3 = load atomic i8, i8* %0 acquire, align 8
+ call void @llvm.lifetime.end(i64 2, i8* %1)
+ ret i8 %3
+; CHECK-LABEL: atomic_min_i8
+; CHECK: lbarx [[DST:[0-9]+]],
+; CHECK-NEXT: extsb [[EXT:[0-9]+]], [[DST]]
+; CHECK-NEXT: cmpw {{[0-9]+}}, [[EXT]]
+; CHECK-NEXT: bge 0
+}
+define i16 @atomic_min_i16() {
+ top:
+ %0 = alloca i16, align 2
+ %1 = bitcast i16* %0 to i8*
+ call void @llvm.lifetime.start(i64 2, i8* %1)
+ store i16 -1, i16* %0, align 2
+ %2 = atomicrmw min i16* %0, i16 0 acq_rel
+ %3 = load atomic i16, i16* %0 acquire, align 8
+ call void @llvm.lifetime.end(i64 2, i8* %1)
+ ret i16 %3
+; CHECK-LABEL: atomic_min_i16
+; CHECK: lharx [[DST:[0-9]+]],
+; CHECK-NEXT: extsh [[EXT:[0-9]+]], [[DST]]
+; CHECK-NEXT: cmpw {{[0-9]+}}, [[EXT]]
+; CHECK-NEXT: bge 0
+}
+
+define i8 @atomic_max_i8() {
+ top:
+ %0 = alloca i8, align 2
+ %1 = bitcast i8* %0 to i8*
+ call void @llvm.lifetime.start(i64 2, i8* %1)
+ store i8 -1, i8* %0, align 2
+ %2 = atomicrmw max i8* %0, i8 0 acq_rel
+ %3 = load atomic i8, i8* %0 acquire, align 8
+ call void @llvm.lifetime.end(i64 2, i8* %1)
+ ret i8 %3
+; CHECK-LABEL: atomic_max_i8
+; CHECK: lbarx [[DST:[0-9]+]],
+; CHECK-NEXT: extsb [[EXT:[0-9]+]], [[DST]]
+; CHECK-NEXT: cmpw {{[0-9]+}}, [[EXT]]
+; CHECK-NEXT: ble 0
+}
+define i16 @atomic_max_i16() {
+ top:
+ %0 = alloca i16, align 2
+ %1 = bitcast i16* %0 to i8*
+ call void @llvm.lifetime.start(i64 2, i8* %1)
+ store i16 -1, i16* %0, align 2
+ %2 = atomicrmw max i16* %0, i16 0 acq_rel
+ %3 = load atomic i16, i16* %0 acquire, align 8
+ call void @llvm.lifetime.end(i64 2, i8* %1)
+ ret i16 %3
+; CHECK-LABEL: atomic_max_i16
+; CHECK: lharx [[DST:[0-9]+]],
+; CHECK-NEXT: extsh [[EXT:[0-9]+]], [[DST]]
+; CHECK-NEXT: cmpw {{[0-9]+}}, [[EXT]]
+; CHECK-NEXT: ble 0
+}
+
+declare void @llvm.lifetime.start(i64, i8*)
+declare void @llvm.lifetime.end(i64, i8*)
4 changes: 0 additions & 4 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5940,10 +5940,6 @@ static inline SmallVector<std::string,10> getTargetFeatures(std::string &cpu)
// is disabled.
HostFeatures["cx16"] = true;
#endif
#if defined(_CPU_PPC64_)
// Temporarily disable partword (i16) atomics due to LLVM bug(30451).
HostFeatures["partword-atomics"] = false;
#endif

// Figure out if we know the cpu_target
cpu = (strcmp(jl_options.cpu_target,"native") ? jl_options.cpu_target :
Expand Down