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:
parent
3491156985
commit
5a44777de2
@ -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;
|
||||||
|
@ -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();
|
||||||
|
18
test/CodeGen/RISCV/rvv/combine-store-fp.ll
Normal file
18
test/CodeGen/RISCV/rvv/combine-store-fp.ll
Normal 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
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user