Backport r296811, r297001, and r327651 from trunk. rhbz#1554349

This commit is contained in:
Tom Stellard 2018-03-19 23:55:28 +00:00
parent 48a8b21ef0
commit b3f19ed18b
4 changed files with 260 additions and 1 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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.