1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 11:13:28 +01:00

[DAGCombine][RISCV] Don't try to trunc-store combined vector stores

DAGCombine's `mergeStoresOfConstantsOrVecElts` optimization is told
whether it's to use vector types and also whether it's to issue a
truncating store. However, the truncating store code path assumes a
scalar integer `ConstantSDNode`, and when using vector types it creates
either a `BUILD_VECTOR` or `CONCAT_VECTORS` to store: neither of which
is a constant.

The `riscv64` target is able to expose a crash here because it switches
on both code paths at the same time. The `f32` is stored as `i32` which
must be promoted to `i64`, necessitating a truncating store.
It also decides later that it prefers a vector store of `v2f32`.

While vector truncating stores are legal, this combine is not able to
emit them. We also don't have a test case. This patch adds an assert to
catch this case more gracefully, and updates one of the caller functions
to the function to turn off the use of truncating stores when preferring
vectors.

Reviewed By: craig.topper

Differential Revision: https://reviews.llvm.org/D103173
This commit is contained in:
Fraser Cormack 2021-05-26 16:04:59 +01:00
parent 3491156985
commit 5a44777de2
3 changed files with 28 additions and 4 deletions

View File

@ -16726,6 +16726,9 @@ bool DAGCombiner::mergeStoresOfConstantsOrVecElts(
if (NumStores < 2) if (NumStores < 2)
return false; return false;
assert((!UseTrunc || !UseVector) &&
"This optimization cannot emit a vector truncating store");
// The latest Node in the DAG. // The latest Node in the DAG.
SDLoc DL(StoreNodes[0].MemNode); SDLoc DL(StoreNodes[0].MemNode);
@ -17221,6 +17224,7 @@ bool DAGCombiner::tryStoreMergeOfConstants(
bool UseVector = (LastLegalVectorType > LastLegalType) && AllowVectors; bool UseVector = (LastLegalVectorType > LastLegalType) && AllowVectors;
unsigned NumElem = (UseVector) ? LastLegalVectorType : LastLegalType; unsigned NumElem = (UseVector) ? LastLegalVectorType : LastLegalType;
bool UseTrunc = LastIntegerTrunc && !UseVector;
// Check if we found a legal integer type that creates a meaningful // Check if we found a legal integer type that creates a meaningful
// merge. // merge.
@ -17251,8 +17255,9 @@ bool DAGCombiner::tryStoreMergeOfConstants(
continue; continue;
} }
MadeChange |= mergeStoresOfConstantsOrVecElts( MadeChange |= mergeStoresOfConstantsOrVecElts(StoreNodes, MemVT, NumElem,
StoreNodes, MemVT, NumElem, true, UseVector, LastIntegerTrunc); /*IsConstantSrc*/ true,
UseVector, UseTrunc);
// Remove merged stores for next iteration. // Remove merged stores for next iteration.
StoreNodes.erase(StoreNodes.begin(), StoreNodes.begin() + NumElem); StoreNodes.erase(StoreNodes.begin(), StoreNodes.begin() + NumElem);
@ -17321,7 +17326,8 @@ bool DAGCombiner::tryStoreMergeOfExtracts(
} }
MadeChange |= mergeStoresOfConstantsOrVecElts( MadeChange |= mergeStoresOfConstantsOrVecElts(
StoreNodes, MemVT, NumStoresToMerge, false, true, false); StoreNodes, MemVT, NumStoresToMerge, /*IsConstantSrc*/ false,
/*UseVector*/ true, /*UseTrunc*/ false);
StoreNodes.erase(StoreNodes.begin(), StoreNodes.begin() + NumStoresToMerge); StoreNodes.erase(StoreNodes.begin(), StoreNodes.begin() + NumStoresToMerge);
NumConsecutiveStores -= NumStoresToMerge; NumConsecutiveStores -= NumStoresToMerge;

View File

@ -8429,7 +8429,7 @@ bool RISCVTargetLowering::decomposeMulByConstant(LLVMContext &Context, EVT VT,
bool RISCVTargetLowering::allowsMisalignedMemoryAccesses( bool RISCVTargetLowering::allowsMisalignedMemoryAccesses(
EVT VT, unsigned AddrSpace, Align Alignment, MachineMemOperand::Flags Flags, EVT VT, unsigned AddrSpace, Align Alignment, MachineMemOperand::Flags Flags,
bool *Fast) const { bool *Fast) const {
if (!VT.isScalableVector()) if (!VT.isVector())
return false; return false;
EVT ElemVT = VT.getVectorElementType(); EVT ElemVT = VT.getVectorElementType();

View File

@ -0,0 +1,18 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple=riscv32 -mattr=+d,+experimental-v -verify-machineinstrs -riscv-v-vector-bits-min=128 < %s | FileCheck %s
; RUN: llc -mtriple=riscv64 -mattr=+d,+experimental-v -verify-machineinstrs -riscv-v-vector-bits-min=128 < %s | FileCheck %s
define void @combine_fp_zero_stores_crash(float* %ptr) {
; CHECK-LABEL: combine_fp_zero_stores_crash:
; CHECK: # %bb.0:
; CHECK-NEXT: addi a0, a0, 4
; CHECK-NEXT: vsetivli zero, 2, e32,mf2,ta,mu
; CHECK-NEXT: vmv.v.i v25, 0
; CHECK-NEXT: vse32.v v25, (a0)
; CHECK-NEXT: ret
%addr1 = getelementptr float, float * %ptr, i64 1
%addr2 = getelementptr float, float * %ptr, i64 2
store float 0.000000e+00, float * %addr1, align 4
store float 0.000000e+00, float * %addr2, align 4
ret void
}