mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-19 19:12:56 +02:00
[Loads] Forward constant vector store to load of first element
InstCombine performs simple forwarding from stores to loads, but currently only handles the case where the load and store have the same size. This extends it to also handle a store of a constant with a larger size followed by a load with a smaller size. This is implemented through ConstantFoldLoadThroughBitcast() which is fairly primitive (e.g. does not allow storing a large integer and then loading a small one), but at least can forward the first element of a vector store. Unfortunately it seems that we currently don't have a generic helper for "read a constant value as a different type", it's all tangled up with other logic in either ConstantFolding or VNCoercion. Differential Revision: https://reviews.llvm.org/D98114
This commit is contained in:
parent
108a3b9085
commit
725bd76263
@ -495,12 +495,15 @@ static Value *getAvailableLoadStore(Instruction *Inst, const Value *Ptr,
|
||||
if (!AreEquivalentAddressValues(StorePtr, Ptr))
|
||||
return nullptr;
|
||||
|
||||
if (IsLoadCSE)
|
||||
*IsLoadCSE = false;
|
||||
|
||||
Value *Val = SI->getValueOperand();
|
||||
if (CastInst::isBitOrNoopPointerCastable(Val->getType(), AccessTy, DL)) {
|
||||
if (IsLoadCSE)
|
||||
*IsLoadCSE = false;
|
||||
if (CastInst::isBitOrNoopPointerCastable(Val->getType(), AccessTy, DL))
|
||||
return Val;
|
||||
}
|
||||
|
||||
if (auto *C = dyn_cast<Constant>(Val))
|
||||
return ConstantFoldLoadThroughBitcast(C, AccessTy, DL);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
@ -22,8 +22,7 @@ define i32 @vec_store_load_first(i32* %p) {
|
||||
; CHECK-LABEL: @vec_store_load_first(
|
||||
; CHECK-NEXT: [[P2:%.*]] = bitcast i32* [[P:%.*]] to <2 x i32>*
|
||||
; CHECK-NEXT: store <2 x i32> <i32 1, i32 2>, <2 x i32>* [[P2]], align 8
|
||||
; CHECK-NEXT: [[LOAD:%.*]] = load i32, i32* [[P]], align 4
|
||||
; CHECK-NEXT: ret i32 [[LOAD]]
|
||||
; CHECK-NEXT: ret i32 1
|
||||
;
|
||||
%p2 = bitcast i32* %p to <2 x i32>*
|
||||
store <2 x i32> <i32 1, i32 2>, <2 x i32>* %p2
|
||||
@ -31,6 +30,19 @@ define i32 @vec_store_load_first(i32* %p) {
|
||||
ret i32 %load
|
||||
}
|
||||
|
||||
define i32 @vec_store_load_first_constexpr(i32* %p) {
|
||||
; CHECK-LABEL: @vec_store_load_first_constexpr(
|
||||
; CHECK-NEXT: [[P2:%.*]] = bitcast i32* [[P:%.*]] to <2 x i32>*
|
||||
; CHECK-NEXT: store <2 x i32> bitcast (i64 ptrtoint (i32 (i32*)* @vec_store_load_first to i64) to <2 x i32>), <2 x i32>* [[P2]], align 8
|
||||
; CHECK-NEXT: [[LOAD:%.*]] = load i32, i32* [[P]], align 4
|
||||
; CHECK-NEXT: ret i32 [[LOAD]]
|
||||
;
|
||||
%p2 = bitcast i32* %p to <2 x i32>*
|
||||
store <2 x i32> bitcast (i64 ptrtoint (i32 (i32*)* @vec_store_load_first to i64) to <2 x i32>), <2 x i32>* %p2, align 8
|
||||
%load = load i32, i32* %p, align 4
|
||||
ret i32 %load
|
||||
}
|
||||
|
||||
define i32 @vec_store_load_second(i32* %p) {
|
||||
; CHECK-LABEL: @vec_store_load_second(
|
||||
; CHECK-NEXT: [[P2:%.*]] = bitcast i32* [[P:%.*]] to <2 x i32>*
|
||||
|
Loading…
Reference in New Issue
Block a user