[llvm] r283219 - [RS4GC] Handle ShuffleVector instruction in findBasePointer
Anna Thomas via llvm-commits
llvm-commits at lists.llvm.org
Tue Oct 4 06:48:37 PDT 2016
Author: annat
Date: Tue Oct 4 08:48:37 2016
New Revision: 283219
URL: http://llvm.org/viewvc/llvm-project?rev=283219&view=rev
Log:
[RS4GC] Handle ShuffleVector instruction in findBasePointer
Summary:
This patch modifies the findBasePointer to handle the shufflevector instruction.
Tests run: RS4GC tests, local downstream tests.
Reviewers: reames, sanjoy
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D25197
Modified:
llvm/trunk/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
llvm/trunk/test/Transforms/RewriteStatepointsForGC/base-vector.ll
Modified: llvm/trunk/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp?rev=283219&r1=283218&r2=283219&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp Tue Oct 4 08:48:37 2016
@@ -676,7 +676,8 @@ static Value *findBasePointer(Value *I,
#ifndef NDEBUG
auto isExpectedBDVType = [](Value *BDV) {
return isa<PHINode>(BDV) || isa<SelectInst>(BDV) ||
- isa<ExtractElementInst>(BDV) || isa<InsertElementInst>(BDV);
+ isa<ExtractElementInst>(BDV) || isa<InsertElementInst>(BDV) ||
+ isa<ShuffleVectorInst>(BDV);
};
#endif
@@ -719,9 +720,11 @@ static Value *findBasePointer(Value *I,
} else if (auto *IE = dyn_cast<InsertElementInst>(Current)) {
visitIncomingValue(IE->getOperand(0)); // vector operand
visitIncomingValue(IE->getOperand(1)); // scalar operand
- } else {
- // There is one known class of instructions we know we don't handle.
- assert(isa<ShuffleVectorInst>(Current));
+ } else if (auto *SV = dyn_cast<ShuffleVectorInst>(Current)) {
+ visitIncomingValue(SV->getOperand(0));
+ visitIncomingValue(SV->getOperand(1));
+ }
+ else {
llvm_unreachable("Unimplemented instruction case");
}
}
@@ -778,12 +781,17 @@ static Value *findBasePointer(Value *I,
// useful in that it drives us to conflict if our input is.
NewState =
meetBDVState(NewState, getStateForInput(EE->getVectorOperand()));
- } else {
+ } else if (auto *IE = dyn_cast<InsertElementInst>(BDV)){
// Given there's a inherent type mismatch between the operands, will
// *always* produce Conflict.
- auto *IE = cast<InsertElementInst>(BDV);
NewState = meetBDVState(NewState, getStateForInput(IE->getOperand(0)));
NewState = meetBDVState(NewState, getStateForInput(IE->getOperand(1)));
+ } else {
+ // The only instance this does not return a Conflict is when both the
+ // vector operands are the same vector.
+ auto *SV = cast<ShuffleVectorInst>(BDV);
+ NewState = meetBDVState(NewState, getStateForInput(SV->getOperand(0)));
+ NewState = meetBDVState(NewState, getStateForInput(SV->getOperand(1)));
}
BDVState OldState = States[BDV];
@@ -855,13 +863,18 @@ static Value *findBasePointer(Value *I,
std::string Name = suffixed_name_or(I, ".base", "base_ee");
return ExtractElementInst::Create(Undef, EE->getIndexOperand(), Name,
EE);
- } else {
- auto *IE = cast<InsertElementInst>(I);
+ } else if (auto *IE = dyn_cast<InsertElementInst>(I)) {
UndefValue *VecUndef = UndefValue::get(IE->getOperand(0)->getType());
UndefValue *ScalarUndef = UndefValue::get(IE->getOperand(1)->getType());
std::string Name = suffixed_name_or(I, ".base", "base_ie");
return InsertElementInst::Create(VecUndef, ScalarUndef,
IE->getOperand(2), Name, IE);
+ } else {
+ auto *SV = cast<ShuffleVectorInst>(I);
+ UndefValue *VecUndef = UndefValue::get(SV->getOperand(0)->getType());
+ std::string Name = suffixed_name_or(I, ".base", "base_sv");
+ return new ShuffleVectorInst(VecUndef, VecUndef, SV->getOperand(2),
+ Name, SV);
}
};
Instruction *BaseInst = MakeBaseInstPlaceholder(I);
@@ -963,8 +976,7 @@ static Value *findBasePointer(Value *I,
// Find the instruction which produces the base for each input. We may
// need to insert a bitcast.
BaseEE->setOperand(0, getBaseForInput(InVal, BaseEE));
- } else {
- auto *BaseIE = cast<InsertElementInst>(State.getBaseValue());
+ } else if (auto *BaseIE = dyn_cast<InsertElementInst>(State.getBaseValue())){
auto *BdvIE = cast<InsertElementInst>(BDV);
auto UpdateOperand = [&](int OperandIdx) {
Value *InVal = BdvIE->getOperand(OperandIdx);
@@ -973,6 +985,16 @@ static Value *findBasePointer(Value *I,
};
UpdateOperand(0); // vector operand
UpdateOperand(1); // scalar operand
+ } else {
+ auto *BaseSV = cast<ShuffleVectorInst>(State.getBaseValue());
+ auto *BdvSV = cast<ShuffleVectorInst>(BDV);
+ auto UpdateOperand = [&](int OperandIdx) {
+ Value *InVal = BdvSV->getOperand(OperandIdx);
+ Value *Base = getBaseForInput(InVal, BaseSV);
+ BaseSV->setOperand(OperandIdx, Base);
+ };
+ UpdateOperand(0); // vector operand
+ UpdateOperand(1); // vector operand
}
}
Modified: llvm/trunk/test/Transforms/RewriteStatepointsForGC/base-vector.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/RewriteStatepointsForGC/base-vector.ll?rev=283219&r1=283218&r2=283219&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/RewriteStatepointsForGC/base-vector.ll (original)
+++ llvm/trunk/test/Transforms/RewriteStatepointsForGC/base-vector.ll Tue Oct 4 08:48:37 2016
@@ -165,4 +165,83 @@ next:
ret i64 addrspace(1)* %objb
}
+; identify base for shufflevector
+define void @test8(i64 addrspace(1)* %obj, i64 %idx) gc "statepoint-example" {
+; CHECK-LABEL: @test8
+; CHECK: %gep = getelementptr i64, i64 addrspace(1)* %obj, i64 1
+; CHECK: %gep2 = getelementptr i64, i64 addrspace(1)* %obj, i64 2
+; CHECK: %vec1.base = insertelement <4 x i64 addrspace(1)*> zeroinitializer, i64 addrspace(1)* %obj, i32 0, !is_base_value !0
+; CHECK: %vec1 = insertelement <4 x i64 addrspace(1)*> undef, i64 addrspace(1)* %gep, i32 0
+; CHECK: %vec2.base = insertelement <4 x i64 addrspace(1)*> zeroinitializer, i64 addrspace(1)* %obj, i32 2, !is_base_value !0
+; CHECK: %vec2 = insertelement <4 x i64 addrspace(1)*> undef, i64 addrspace(1)* %gep2, i32 2
+; CHECK: %vec.base = shufflevector <4 x i64 addrspace(1)*> %vec1.base, <4 x i64 addrspace(1)*> %vec2.base, <2 x i32> <i32 0, i32 2>, !is_base_value !0
+; CHECK: %vec = shufflevector <4 x i64 addrspace(1)*> %vec1, <4 x i64 addrspace(1)*> %vec2, <2 x i32> <i32 0, i32 2>
+; CHECK: %bdv.base = extractelement <2 x i64 addrspace(1)*> %vec.base, i64 %idx, !is_base_value !0
+; CHECK: %bdv = extractelement <2 x i64 addrspace(1)*> %vec, i64 %idx
+; CHECK: gc.statepoint
+; CHECK: gc.relocate
+; CHECK-DAG: (%bdv.base, %bdv)
+entry:
+ %gep = getelementptr i64, i64 addrspace(1)* %obj, i64 1
+ %gep2 = getelementptr i64, i64 addrspace(1)* %obj, i64 2
+ %vec1 = insertelement <4 x i64 addrspace(1)*> undef, i64 addrspace(1)* %gep, i32 0
+ %vec2 = insertelement <4 x i64 addrspace(1)*> undef, i64 addrspace(1)* %gep2, i32 2
+ %vec = shufflevector <4 x i64 addrspace(1)*> %vec1, <4 x i64 addrspace(1)*> %vec2, <2 x i32> <i32 0, i32 2>
+ %bdv = extractelement <2 x i64 addrspace(1)*> %vec, i64 %idx
+ call void @do_safepoint() [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0) ]
+ call void @use(i64 addrspace(1)* %bdv)
+ ret void
+}
+
+; Since the same 'base' vector is used in the shuffle operands, we do not need
+; create a shufflevector base.
+define void @test9(<4 x i64 addrspace(1)*> %vec1, i64 %idx) gc "statepoint-example" {
+; CHECK-LABEL: @test9
+; CHECK: %vec = shufflevector <4 x i64 addrspace(1)*> %vec1, <4 x i64 addrspace(1)*> %vec1, <2 x i32> <i32 0, i32 2>
+; CHECK: %base_ee = extractelement <4 x i64 addrspace(1)*> %vec1, i64 %idx, !is_base_value !0
+; CHECK: %bdv = extractelement <2 x i64 addrspace(1)*> %vec, i64 %idx
+; CHECK: gc.statepoint
+; CHECK: gc.relocate
+; CHECK-DAG: (%base_ee, %bdv)
+entry:
+ ; shrinking vec1 into vec
+ %vec = shufflevector <4 x i64 addrspace(1)*> %vec1, <4 x i64 addrspace(1)*> %vec1, <2 x i32> <i32 0, i32 2>
+ %bdv = extractelement <2 x i64 addrspace(1)*> %vec, i64 %idx
+ call void @do_safepoint() [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0) ]
+ call void @use(i64 addrspace(1)* %bdv)
+ ret void
+}
+
+; vector operand of shufflevector is a phi
+define i64 addrspace(1)* @test10(i1 %cnd, i64 addrspace(1)* %obj, i64 addrspace(1)* %obj2) gc "statepoint-example" {
+; CHECK-LABEL: @test10
+entry:
+ %vec1 = insertelement <4 x i64 addrspace(1)*> undef, i64 addrspace(1)* %obj, i32 0
+ br i1 %cnd, label %here, label %merge
+
+here:
+ %vec2 = insertelement <4 x i64 addrspace(1)*> undef, i64 addrspace(1)* %obj2, i32 2
+ br label %merge
+
+merge: ; preds = %merge, %entry, %here
+; CHECK-LABEL: merge:
+; CHECK: %vec.base = phi <4 x i64 addrspace(1)*> [ %vec1.base, %entry ], [ %vec2.base, %here ], [ %vec3.base, %merge ], !is_base_value !0
+; CHECK: vec
+; CHECK: vec3.base = shufflevector <4 x i64 addrspace(1)*> %vec.base, <4 x i64 addrspace(1)*> %vec.base
+; CHECK: vec3
+; CHECK: bdv.base
+; CHECK: bdv
+ %vec = phi <4 x i64 addrspace(1)*> [ %vec1, %entry ], [ %vec2, %here], [ %vec3, %merge]
+ %vec3 = shufflevector <4 x i64 addrspace(1)*> %vec, <4 x i64 addrspace(1)*> %vec, <4 x i32> <i32 2, i32 0, i32 1, i32 3>
+ %bdv = extractelement <4 x i64 addrspace(1)*> %vec3, i32 0
+ br i1 %cnd, label %merge, label %next
+
+next:
+; CHECK-LABEL: next:
+; CHECK: gc.statepoint
+; CHECK: gc.relocate
+; CHECK-DAG: (%bdv.base, %bdv)
+ call void @do_safepoint() [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0) ]
+ ret i64 addrspace(1)* %bdv
+}
declare void @do_safepoint()
More information about the llvm-commits
mailing list