mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 03:02:36 +01:00
[Scalarizer] Propagate IR flags
Summary: The motivation for this was to propagate fast-math flags like nnan and ninf on vector floating point operations to the corresponding scalar operations to take advantage of follow-on optimizations. But I think the same argument applies to all of our IR flags: if they apply to the vector operation then they also apply to all the individual scalar operations, and they might enable follow-on optimizations. Subscribers: hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D63593 llvm-svn: 364051
This commit is contained in:
parent
5920f219f2
commit
55a0dcdf87
@ -200,7 +200,7 @@ private:
|
||||
Scatterer scatter(Instruction *Point, Value *V);
|
||||
void gather(Instruction *Op, const ValueVector &CV);
|
||||
bool canTransferMetadata(unsigned Kind);
|
||||
void transferMetadata(Instruction *Op, const ValueVector &CV);
|
||||
void transferMetadataAndIRFlags(Instruction *Op, const ValueVector &CV);
|
||||
bool getVectorLayout(Type *Ty, unsigned Alignment, VectorLayout &Layout,
|
||||
const DataLayout &DL);
|
||||
bool finish();
|
||||
@ -361,7 +361,7 @@ void ScalarizerVisitor::gather(Instruction *Op, const ValueVector &CV) {
|
||||
for (unsigned I = 0, E = Op->getNumOperands(); I != E; ++I)
|
||||
Op->setOperand(I, UndefValue::get(Op->getOperand(I)->getType()));
|
||||
|
||||
transferMetadata(Op, CV);
|
||||
transferMetadataAndIRFlags(Op, CV);
|
||||
|
||||
// If we already have a scattered form of Op (created from ExtractElements
|
||||
// of Op itself), replace them with the new form.
|
||||
@ -397,7 +397,8 @@ bool ScalarizerVisitor::canTransferMetadata(unsigned Tag) {
|
||||
|
||||
// Transfer metadata from Op to the instructions in CV if it is known
|
||||
// to be safe to do so.
|
||||
void ScalarizerVisitor::transferMetadata(Instruction *Op, const ValueVector &CV) {
|
||||
void ScalarizerVisitor::transferMetadataAndIRFlags(Instruction *Op,
|
||||
const ValueVector &CV) {
|
||||
SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
|
||||
Op->getAllMetadataOtherThanDebugLoc(MDs);
|
||||
for (unsigned I = 0, E = CV.size(); I != E; ++I) {
|
||||
@ -405,6 +406,7 @@ void ScalarizerVisitor::transferMetadata(Instruction *Op, const ValueVector &CV)
|
||||
for (const auto &MD : MDs)
|
||||
if (canTransferMetadata(MD.first))
|
||||
New->setMetadata(MD.first, MD.second);
|
||||
New->copyIRFlags(Op);
|
||||
if (Op->getDebugLoc() && !New->getDebugLoc())
|
||||
New->setDebugLoc(Op->getDebugLoc());
|
||||
}
|
||||
@ -809,7 +811,7 @@ bool ScalarizerVisitor::visitStoreInst(StoreInst &SI) {
|
||||
unsigned Align = Layout.getElemAlign(I);
|
||||
Stores[I] = Builder.CreateAlignedStore(Val[I], Ptr[I], Align);
|
||||
}
|
||||
transferMetadata(&SI, Stores);
|
||||
transferMetadataAndIRFlags(&SI, Stores);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -506,6 +506,59 @@ exit:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Check that IR flags are preserved.
|
||||
define <2 x i32> @f16(<2 x i32> %i, <2 x i32> %j) {
|
||||
; CHECK-LABEL: @f16(
|
||||
; CHECK: %res.i0 = add nuw nsw i32
|
||||
; CHECK: %res.i1 = add nuw nsw i32
|
||||
%res = add nuw nsw <2 x i32> %i, %j
|
||||
ret <2 x i32> %res
|
||||
}
|
||||
define <2 x i32> @f17(<2 x i32> %i, <2 x i32> %j) {
|
||||
; CHECK-LABEL: @f17(
|
||||
; CHECK: %res.i0 = sdiv exact i32
|
||||
; CHECK: %res.i1 = sdiv exact i32
|
||||
%res = sdiv exact <2 x i32> %i, %j
|
||||
ret <2 x i32> %res
|
||||
}
|
||||
define <2 x float> @f18(<2 x float> %x, <2 x float> %y) {
|
||||
; CHECK-LABEL: @f18(
|
||||
; CHECK: %res.i0 = fadd fast float
|
||||
; CHECK: %res.i1 = fadd fast float
|
||||
%res = fadd fast <2 x float> %x, %y
|
||||
ret <2 x float> %res
|
||||
}
|
||||
define <2 x float> @f19(<2 x float> %x) {
|
||||
; CHECK-LABEL: @f19(
|
||||
; CHECK: %res.i0 = fneg fast float
|
||||
; CHECK: %res.i1 = fneg fast float
|
||||
%res = fneg fast <2 x float> %x
|
||||
ret <2 x float> %res
|
||||
}
|
||||
define <2 x i1> @f20(<2 x float> %x, <2 x float> %y) {
|
||||
; CHECK-LABEL: @f20(
|
||||
; CHECK: %res.i0 = fcmp fast ogt float
|
||||
; CHECK: %res.i1 = fcmp fast ogt float
|
||||
%res = fcmp fast ogt <2 x float> %x, %y
|
||||
ret <2 x i1> %res
|
||||
}
|
||||
declare <2 x float> @llvm.sqrt.v2f32(<2 x float>)
|
||||
define <2 x float> @f21(<2 x float> %x) {
|
||||
; CHECK-LABEL: @f21(
|
||||
; CHECK: %res.i0 = call fast float @llvm.sqrt.f32
|
||||
; CHECK: %res.i1 = call fast float @llvm.sqrt.f32
|
||||
%res = call fast <2 x float> @llvm.sqrt.v2f32(<2 x float> %x)
|
||||
ret <2 x float> %res
|
||||
}
|
||||
declare <2 x float> @llvm.fma.v2f32(<2 x float>, <2 x float>, <2 x float>)
|
||||
define <2 x float> @f22(<2 x float> %x, <2 x float> %y, <2 x float> %z) {
|
||||
; CHECK-LABEL: @f22(
|
||||
; CHECK: %res.i0 = call fast float @llvm.fma.f32
|
||||
; CHECK: %res.i1 = call fast float @llvm.fma.f32
|
||||
%res = call fast <2 x float> @llvm.fma.v2f32(<2 x float> %x, <2 x float> %y, <2 x float> %z)
|
||||
ret <2 x float> %res
|
||||
}
|
||||
|
||||
!0 = !{ !"root" }
|
||||
!1 = !{ !"set1", !0 }
|
||||
!2 = !{ !"set2", !0 }
|
||||
|
Loading…
Reference in New Issue
Block a user