forked from OSchip/llvm-project
[SelectionDAGBuilder] Fix ISD::FREEZE creation for structs with fields of different types.
The previous code used the type of the first field for the VT passed to getNode for every field. I've based the implementation here off what is done in visitSelect as it removes the need to special case aggregates. Differential Revision: https://reviews.llvm.org/D77093
This commit is contained in:
parent
77e2493602
commit
07ed1fb597
|
@ -10537,22 +10537,19 @@ void SelectionDAGBuilder::visitSwitch(const SwitchInst &SI) {
|
|||
}
|
||||
|
||||
void SelectionDAGBuilder::visitFreeze(const FreezeInst &I) {
|
||||
SDNodeFlags Flags;
|
||||
SmallVector<EVT, 4> ValueVTs;
|
||||
ComputeValueVTs(DAG.getTargetLoweringInfo(), DAG.getDataLayout(), I.getType(),
|
||||
ValueVTs);
|
||||
unsigned NumValues = ValueVTs.size();
|
||||
if (NumValues == 0) return;
|
||||
|
||||
SmallVector<SDValue, 4> Values(NumValues);
|
||||
SDValue Op = getValue(I.getOperand(0));
|
||||
if (I.getOperand(0)->getType()->isAggregateType()) {
|
||||
EVT VT = Op.getValueType();
|
||||
SmallVector<SDValue, 1> Values;
|
||||
for (unsigned i = 0; i < Op.getNumOperands(); ++i) {
|
||||
SDValue Arg(Op.getNode(), i);
|
||||
SDValue UnNodeValue = DAG.getNode(ISD::FREEZE, getCurSDLoc(), VT, Arg, Flags);
|
||||
Values.push_back(UnNodeValue);
|
||||
}
|
||||
SDValue MergedValue = DAG.getMergeValues(Values, getCurSDLoc());
|
||||
setValue(&I, MergedValue);
|
||||
} else {
|
||||
SDValue UnNodeValue = DAG.getNode(ISD::FREEZE, getCurSDLoc(), Op.getValueType(),
|
||||
Op, Flags);
|
||||
setValue(&I, UnNodeValue);
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i != NumValues; ++i)
|
||||
Values[i] = DAG.getNode(ISD::FREEZE, getCurSDLoc(), ValueVTs[i],
|
||||
SDValue(Op.getNode(), Op.getResNo() + i));
|
||||
|
||||
setValue(&I, DAG.getNode(ISD::MERGE_VALUES, getCurSDLoc(),
|
||||
DAG.getVTList(ValueVTs), Values));
|
||||
}
|
||||
|
|
|
@ -97,6 +97,20 @@ define i32 @freeze_anonstruct() {
|
|||
ret i32 %t1
|
||||
}
|
||||
|
||||
define i32 @freeze_anonstruct2() {
|
||||
; X86ASM-LABEL: freeze_anonstruct2:
|
||||
; X86ASM: # %bb.0:
|
||||
; X86ASM-NEXT: movzwl %ax, %eax
|
||||
; X86ASM-NEXT: addl %eax, %eax
|
||||
; X86ASM-NEXT: retq
|
||||
%y1 = freeze {i32, i16} undef
|
||||
%v1 = extractvalue {i32, i16} %y1, 0
|
||||
%v2 = extractvalue {i32, i16} %y1, 1
|
||||
%z2 = zext i16 %v2 to i32
|
||||
%t1 = add i32 %v1, %z2
|
||||
ret i32 %t1
|
||||
}
|
||||
|
||||
define i64 @freeze_array() {
|
||||
; X86ASM-LABEL: freeze_array:
|
||||
; X86ASM: # %bb.0:
|
||||
|
|
Loading…
Reference in New Issue