Backport r296811, r297001, and r327651 from trunk. rhbz#1554349
This commit is contained in:
parent
48a8b21ef0
commit
b3f19ed18b
|
@ -0,0 +1,77 @@
|
|||
From 66e43b0a8e5616a4762eedee9bd030a49b9d6545 Mon Sep 17 00:00:00 2001
|
||||
From: Guozhi Wei <carrot@google.com>
|
||||
Date: Thu, 2 Mar 2017 21:07:59 +0000
|
||||
Subject: [PATCH 1/3] [PPC] Fix code generation for bswap(int32) followed by
|
||||
store16
|
||||
|
||||
This patch fixes pr32063.
|
||||
|
||||
Current code in PPCTargetLowering::PerformDAGCombine can transform
|
||||
|
||||
bswap
|
||||
store
|
||||
|
||||
into a single PPCISD::STBRX instruction. but it doesn't consider the case that the operand size of bswap may be larger than store size. When it occurs, we need 2 modifications,
|
||||
|
||||
1 For the last operand of PPCISD::STBRX, we should not use DAG.getValueType(N->getOperand(1).getValueType()), instead we should use cast<StoreSDNode>(N)->getMemoryVT().
|
||||
|
||||
2 Before PPCISD::STBRX, we need to shift the original operand of bswap to the right side.
|
||||
|
||||
Differential Revision: https://reviews.llvm.org/D30362
|
||||
|
||||
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@296811 91177308-0d34-0410-b5e6-96231b3b80d8
|
||||
---
|
||||
lib/Target/PowerPC/PPCISelLowering.cpp | 12 ++++++++++--
|
||||
test/CodeGen/PowerPC/pr32063.ll | 16 ++++++++++++++++
|
||||
2 files changed, 26 insertions(+), 2 deletions(-)
|
||||
create mode 100644 test/CodeGen/PowerPC/pr32063.ll
|
||||
|
||||
diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp
|
||||
index 6313082..c8eb6f1 100644
|
||||
--- a/lib/Target/PowerPC/PPCISelLowering.cpp
|
||||
+++ b/lib/Target/PowerPC/PPCISelLowering.cpp
|
||||
@@ -11226,9 +11226,17 @@ SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N,
|
||||
if (BSwapOp.getValueType() == MVT::i16)
|
||||
BSwapOp = DAG.getNode(ISD::ANY_EXTEND, dl, MVT::i32, BSwapOp);
|
||||
|
||||
+ // If the type of BSWAP operand is wider than stored memory width
|
||||
+ // it need to be shifted to the right side before STBRX.
|
||||
+ EVT mVT = cast<StoreSDNode>(N)->getMemoryVT();
|
||||
+ if (Op1VT.bitsGT(mVT)) {
|
||||
+ int shift = Op1VT.getSizeInBits() - mVT.getSizeInBits();
|
||||
+ BSwapOp = DAG.getNode(ISD::SRL, dl, Op1VT, BSwapOp,
|
||||
+ DAG.getConstant(shift, dl, MVT::i32));
|
||||
+ }
|
||||
+
|
||||
SDValue Ops[] = {
|
||||
- N->getOperand(0), BSwapOp, N->getOperand(2),
|
||||
- DAG.getValueType(N->getOperand(1).getValueType())
|
||||
+ N->getOperand(0), BSwapOp, N->getOperand(2), DAG.getValueType(mVT)
|
||||
};
|
||||
return
|
||||
DAG.getMemIntrinsicNode(PPCISD::STBRX, dl, DAG.getVTList(MVT::Other),
|
||||
diff --git a/test/CodeGen/PowerPC/pr32063.ll b/test/CodeGen/PowerPC/pr32063.ll
|
||||
new file mode 100644
|
||||
index 0000000..f031ec8
|
||||
--- /dev/null
|
||||
+++ b/test/CodeGen/PowerPC/pr32063.ll
|
||||
@@ -0,0 +1,16 @@
|
||||
+; RUN: llc -O2 < %s | FileCheck %s
|
||||
+target triple = "powerpc64le-linux-gnu"
|
||||
+
|
||||
+define void @foo(i32 %v, i16* %p) {
|
||||
+ %1 = and i32 %v, -65536
|
||||
+ %2 = tail call i32 @llvm.bswap.i32(i32 %1)
|
||||
+ %conv = trunc i32 %2 to i16
|
||||
+ store i16 %conv, i16* %p
|
||||
+ ret void
|
||||
+
|
||||
+; CHECK: srwi
|
||||
+; CHECK: sthbrx
|
||||
+; CHECK-NOT: stwbrx
|
||||
+}
|
||||
+
|
||||
+declare i32 @llvm.bswap.i32(i32)
|
||||
--
|
||||
1.8.3.1
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
From 88e57f376eabc375cd9f374369cf9e8e4dcb90af Mon Sep 17 00:00:00 2001
|
||||
From: Nemanja Ivanovic <nemanja.i.ibm@gmail.com>
|
||||
Date: Mon, 6 Mar 2017 07:32:13 +0000
|
||||
Subject: [PATCH 2/3] [PowerPC] Fix failure with STBRX when store is narrower
|
||||
than the bswap
|
||||
|
||||
Fixes a crash caused by r296811 by truncating the input of the STBRX node
|
||||
when the bswap is wider than i32.
|
||||
|
||||
Fixes https://bugs.llvm.org/show_bug.cgi?id=32140
|
||||
|
||||
Differential Revision: https://reviews.llvm.org/D30615
|
||||
|
||||
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@297001 91177308-0d34-0410-b5e6-96231b3b80d8
|
||||
---
|
||||
lib/Target/PowerPC/PPCISelLowering.cpp | 7 ++--
|
||||
test/CodeGen/PowerPC/pr32140.ll | 59 ++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 64 insertions(+), 2 deletions(-)
|
||||
create mode 100644 test/CodeGen/PowerPC/pr32140.ll
|
||||
|
||||
diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp
|
||||
index c8eb6f1..521bb32 100644
|
||||
--- a/lib/Target/PowerPC/PPCISelLowering.cpp
|
||||
+++ b/lib/Target/PowerPC/PPCISelLowering.cpp
|
||||
@@ -11230,9 +11230,12 @@ SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N,
|
||||
// it need to be shifted to the right side before STBRX.
|
||||
EVT mVT = cast<StoreSDNode>(N)->getMemoryVT();
|
||||
if (Op1VT.bitsGT(mVT)) {
|
||||
- int shift = Op1VT.getSizeInBits() - mVT.getSizeInBits();
|
||||
+ int Shift = Op1VT.getSizeInBits() - mVT.getSizeInBits();
|
||||
BSwapOp = DAG.getNode(ISD::SRL, dl, Op1VT, BSwapOp,
|
||||
- DAG.getConstant(shift, dl, MVT::i32));
|
||||
+ DAG.getConstant(Shift, dl, MVT::i32));
|
||||
+ // Need to truncate if this is a bswap of i64 stored as i32/i16.
|
||||
+ if (Op1VT == MVT::i64)
|
||||
+ BSwapOp = DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, BSwapOp);
|
||||
}
|
||||
|
||||
SDValue Ops[] = {
|
||||
diff --git a/test/CodeGen/PowerPC/pr32140.ll b/test/CodeGen/PowerPC/pr32140.ll
|
||||
new file mode 100644
|
||||
index 0000000..827a904
|
||||
--- /dev/null
|
||||
+++ b/test/CodeGen/PowerPC/pr32140.ll
|
||||
@@ -0,0 +1,59 @@
|
||||
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
+; RUN: llc -mtriple=powerpc64le-linux-gnu -mcpu=pwr8 < %s | FileCheck %s
|
||||
+; RUN: llc -mtriple=powerpc64-linux-gnu -mcpu=pwr8 < %s | FileCheck %s
|
||||
+
|
||||
+@as = common local_unnamed_addr global i16 0, align 2
|
||||
+@bs = common local_unnamed_addr global i16 0, align 2
|
||||
+@ai = common local_unnamed_addr global i32 0, align 4
|
||||
+@bi = common local_unnamed_addr global i32 0, align 4
|
||||
+
|
||||
+define void @bswapStorei64Toi32() {
|
||||
+; CHECK-LABEL: bswapStorei64Toi32:
|
||||
+; CHECK: # BB#0: # %entry
|
||||
+; CHECK: lwa 3, 0(3)
|
||||
+; CHECK-NEXT: rldicl 3, 3, 32, 32
|
||||
+; CHECK-NEXT: stwbrx 3, 0, 4
|
||||
+; CHECK-NEXT: blr
|
||||
+entry:
|
||||
+ %0 = load i32, i32* @ai, align 4
|
||||
+ %conv.i = sext i32 %0 to i64
|
||||
+ %or26.i = tail call i64 @llvm.bswap.i64(i64 %conv.i)
|
||||
+ %conv = trunc i64 %or26.i to i32
|
||||
+ store i32 %conv, i32* @bi, align 4
|
||||
+ ret void
|
||||
+}
|
||||
+
|
||||
+define void @bswapStorei32Toi16() {
|
||||
+; CHECK-LABEL: bswapStorei32Toi16:
|
||||
+; CHECK: # BB#0: # %entry
|
||||
+; CHECK: lha 3, 0(3)
|
||||
+; CHECK-NEXT: srwi 3, 3, 16
|
||||
+; CHECK-NEXT: sthbrx 3, 0, 4
|
||||
+; CHECK-NEXT: blr
|
||||
+entry:
|
||||
+ %0 = load i16, i16* @as, align 2
|
||||
+ %conv.i = sext i16 %0 to i32
|
||||
+ %or26.i = tail call i32 @llvm.bswap.i32(i32 %conv.i)
|
||||
+ %conv = trunc i32 %or26.i to i16
|
||||
+ store i16 %conv, i16* @bs, align 2
|
||||
+ ret void
|
||||
+}
|
||||
+
|
||||
+define void @bswapStorei64Toi16() {
|
||||
+; CHECK-LABEL: bswapStorei64Toi16:
|
||||
+; CHECK: # BB#0: # %entry
|
||||
+; CHECK: lha 3, 0(3)
|
||||
+; CHECK-NEXT: rldicl 3, 3, 16, 48
|
||||
+; CHECK-NEXT: sthbrx 3, 0, 4
|
||||
+; CHECK-NEXT: blr
|
||||
+entry:
|
||||
+ %0 = load i16, i16* @as, align 2
|
||||
+ %conv.i = sext i16 %0 to i64
|
||||
+ %or26.i = tail call i64 @llvm.bswap.i64(i64 %conv.i)
|
||||
+ %conv = trunc i64 %or26.i to i16
|
||||
+ store i16 %conv, i16* @bs, align 2
|
||||
+ ret void
|
||||
+}
|
||||
+
|
||||
+declare i32 @llvm.bswap.i32(i32)
|
||||
+declare i64 @llvm.bswap.i64(i64)
|
||||
--
|
||||
1.8.3.1
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
From 8578ad1fb9aa7ebc7e6da266371b8fd58e67633f Mon Sep 17 00:00:00 2001
|
||||
From: Guozhi Wei <carrot@google.com>
|
||||
Date: Thu, 15 Mar 2018 17:49:12 +0000
|
||||
Subject: [PATCH 3/3] [PPC] Avoid non-simple MVT in STBRX optimization
|
||||
|
||||
PR35402 triggered this case. It bswap and stores a 48bit value, current STBRX optimization transforms it into STBRX. Unfortunately 48bit is not a simple MVT, there is no PPC instruction to support it, and it can't be automatically expanded by llvm, so caused a crash.
|
||||
|
||||
This patch detects the non-simple MVT and returns early.
|
||||
|
||||
Differential Revision: https://reviews.llvm.org/D44500
|
||||
|
||||
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@327651 91177308-0d34-0410-b5e6-96231b3b80d8
|
||||
---
|
||||
lib/Target/PowerPC/PPCISelLowering.cpp | 6 +++++-
|
||||
test/CodeGen/PowerPC/pr35402.ll | 18 ++++++++++++++++++
|
||||
2 files changed, 23 insertions(+), 1 deletion(-)
|
||||
create mode 100644 test/CodeGen/PowerPC/pr35402.ll
|
||||
|
||||
diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp
|
||||
index 521bb32..3c37306 100644
|
||||
--- a/lib/Target/PowerPC/PPCISelLowering.cpp
|
||||
+++ b/lib/Target/PowerPC/PPCISelLowering.cpp
|
||||
@@ -11221,6 +11221,11 @@ SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N,
|
||||
N->getOperand(1).getValueType() == MVT::i16 ||
|
||||
(Subtarget.hasLDBRX() && Subtarget.isPPC64() &&
|
||||
N->getOperand(1).getValueType() == MVT::i64))) {
|
||||
+ // STBRX can only handle simple types.
|
||||
+ EVT mVT = cast<StoreSDNode>(N)->getMemoryVT();
|
||||
+ if (mVT.isExtended())
|
||||
+ break;
|
||||
+
|
||||
SDValue BSwapOp = N->getOperand(1).getOperand(0);
|
||||
// Do an any-extend to 32-bits if this is a half-word input.
|
||||
if (BSwapOp.getValueType() == MVT::i16)
|
||||
@@ -11228,7 +11233,6 @@ SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N,
|
||||
|
||||
// If the type of BSWAP operand is wider than stored memory width
|
||||
// it need to be shifted to the right side before STBRX.
|
||||
- EVT mVT = cast<StoreSDNode>(N)->getMemoryVT();
|
||||
if (Op1VT.bitsGT(mVT)) {
|
||||
int Shift = Op1VT.getSizeInBits() - mVT.getSizeInBits();
|
||||
BSwapOp = DAG.getNode(ISD::SRL, dl, Op1VT, BSwapOp,
|
||||
diff --git a/test/CodeGen/PowerPC/pr35402.ll b/test/CodeGen/PowerPC/pr35402.ll
|
||||
new file mode 100644
|
||||
index 0000000..06e6d96
|
||||
--- /dev/null
|
||||
+++ b/test/CodeGen/PowerPC/pr35402.ll
|
||||
@@ -0,0 +1,18 @@
|
||||
+; RUN: llc -O2 < %s | FileCheck %s
|
||||
+target triple = "powerpc64le-linux-gnu"
|
||||
+
|
||||
+define void @test(i8* %p, i64 %data) {
|
||||
+entry:
|
||||
+ %0 = tail call i64 @llvm.bswap.i64(i64 %data)
|
||||
+ %ptr = bitcast i8* %p to i48*
|
||||
+ %val = trunc i64 %0 to i48
|
||||
+ store i48 %val, i48* %ptr, align 1
|
||||
+ ret void
|
||||
+
|
||||
+; CHECK: sth
|
||||
+; CHECK: stw
|
||||
+; CHECK-NOT: stdbrx
|
||||
+
|
||||
+}
|
||||
+
|
||||
+declare i64 @llvm.bswap.i64(i64)
|
||||
--
|
||||
1.8.3.1
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
Name: llvm
|
||||
Version: 4.0.1
|
||||
Release: 2%{?dist}
|
||||
Release: 3%{?dist}
|
||||
Summary: The Low Level Virtual Machine
|
||||
|
||||
License: NCSA
|
||||
|
@ -24,6 +24,9 @@ Patch4: 0001-Revert-Revert-CMake-Move-sphinx-detection-into-AddSp.patch
|
|||
Patch5: 0001-CMake-Fix-docs-llvm-man-target-when-clang-llvm-is-in.patch
|
||||
Patch6: 0001-CMake-Add-LLVM_UTILS_INSTALL_DIR-option.patch
|
||||
Patch7: 0001-DebugInfo-Fix-potential-CU-mismatch-for-SubprogramSc.patch
|
||||
Patch8: 0001-PPC-Fix-code-generation-for-bswap-int32-followed-by-.patch
|
||||
Patch9: 0002-PowerPC-Fix-failure-with-STBRX-when-store-is-narrowe.patch
|
||||
Patch10: 0003-PPC-Avoid-non-simple-MVT-in-STBRX-optimization.patch
|
||||
|
||||
BuildRequires: cmake
|
||||
BuildRequires: zlib-devel
|
||||
|
@ -205,6 +208,9 @@ fi
|
|||
%{_libdir}/cmake/llvm/LLVMStaticExports.cmake
|
||||
|
||||
%changelog
|
||||
* Mon Mar 19 2018 Tom Stellard <tstellar@redhat.com> - 4.0.1-3
|
||||
- Backport r296811, r297001, and r327651 from trunk. rhbz#1554349
|
||||
|
||||
* Tue Nov 21 2017 Tom Stellard <tstellar@redhat.com> - 4.0.1-2
|
||||
- Backport r318289 to fix a debuginfo issue with rust.
|
||||
|
||||
|
|
Loading…
Reference in New Issue