Skip to content

Commit e53b7d1

Browse files
committed
Make codegen able to handle values of empty types. This is one way
to fix PR9900. I will keep it open until sable is able to comment on it. llvm-svn: 131294
1 parent c586166 commit e53b7d1

File tree

5 files changed

+136
-6
lines changed

5 files changed

+136
-6
lines changed

llvm/include/llvm/Type.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,9 @@ class Type : public AbstractTypeUser {
273273
/// @brief Determine if this type could be losslessly bitcast to Ty
274274
bool canLosslesslyBitCastTo(const Type *Ty) const;
275275

276+
/// isEmptyTy - Return true if this type is empty, that is, it has no
277+
/// elements or all its elements are empty.
278+
bool isEmptyTy() const;
276279

277280
/// Here are some useful little methods to query what type derived types are
278281
/// Note that all other types can just compare to see if this == Type::xxxTy;

llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,10 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf) {
155155
const PHINode *PN = dyn_cast<PHINode>(I); ++I) {
156156
if (PN->use_empty()) continue;
157157

158+
// Skip empty types
159+
if (PN->getType()->isEmptyTy())
160+
continue;
161+
158162
DebugLoc DL = PN->getDebugLoc();
159163
unsigned PHIReg = ValueMap[PN];
160164
assert(PHIReg && "PHI node does not have an assigned virtual register!");

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1175,6 +1175,10 @@ void SelectionDAGBuilder::visitRet(const ReturnInst &I) {
11751175
/// created for it, emit nodes to copy the value into the virtual
11761176
/// registers.
11771177
void SelectionDAGBuilder::CopyToExportRegsIfNeeded(const Value *V) {
1178+
// Skip empty types
1179+
if (V->getType()->isEmptyTy())
1180+
return;
1181+
11781182
DenseMap<const Value *, unsigned>::iterator VMI = FuncInfo.ValueMap.find(V);
11791183
if (VMI != FuncInfo.ValueMap.end()) {
11801184
assert(!V->use_empty() && "Unused value assigned virtual registers!");
@@ -2810,16 +2814,18 @@ void SelectionDAGBuilder::visitInsertValue(const InsertValueInst &I) {
28102814
SmallVector<SDValue, 4> Values(NumAggValues);
28112815

28122816
SDValue Agg = getValue(Op0);
2813-
SDValue Val = getValue(Op1);
28142817
unsigned i = 0;
28152818
// Copy the beginning value(s) from the original aggregate.
28162819
for (; i != LinearIndex; ++i)
28172820
Values[i] = IntoUndef ? DAG.getUNDEF(AggValueVTs[i]) :
28182821
SDValue(Agg.getNode(), Agg.getResNo() + i);
28192822
// Copy values from the inserted value(s).
2820-
for (; i != LinearIndex + NumValValues; ++i)
2821-
Values[i] = FromUndef ? DAG.getUNDEF(AggValueVTs[i]) :
2822-
SDValue(Val.getNode(), Val.getResNo() + i - LinearIndex);
2823+
if (NumValValues) {
2824+
SDValue Val = getValue(Op1);
2825+
for (; i != LinearIndex + NumValValues; ++i)
2826+
Values[i] = FromUndef ? DAG.getUNDEF(AggValueVTs[i]) :
2827+
SDValue(Val.getNode(), Val.getResNo() + i - LinearIndex);
2828+
}
28232829
// Copy remaining value(s) from the original aggregate.
28242830
for (; i != NumAggValues; ++i)
28252831
Values[i] = IntoUndef ? DAG.getUNDEF(AggValueVTs[i]) :
@@ -2842,6 +2848,13 @@ void SelectionDAGBuilder::visitExtractValue(const ExtractValueInst &I) {
28422848
ComputeValueVTs(TLI, ValTy, ValValueVTs);
28432849

28442850
unsigned NumValValues = ValValueVTs.size();
2851+
2852+
// Ignore a extractvalue that produces an empty object
2853+
if (!NumValValues) {
2854+
setValue(&I, DAG.getUNDEF(MVT(MVT::Other)));
2855+
return;
2856+
}
2857+
28452858
SmallVector<SDValue, 4> Values(NumValValues);
28462859

28472860
SDValue Agg = getValue(Op0);
@@ -4827,8 +4840,14 @@ void SelectionDAGBuilder::LowerCallTo(ImmutableCallSite CS, SDValue Callee,
48274840

48284841
for (ImmutableCallSite::arg_iterator i = CS.arg_begin(), e = CS.arg_end();
48294842
i != e; ++i) {
4830-
SDValue ArgNode = getValue(*i);
4831-
Entry.Node = ArgNode; Entry.Ty = (*i)->getType();
4843+
const Value *V = *i;
4844+
4845+
// Skip empty types
4846+
if (V->getType()->isEmptyTy())
4847+
continue;
4848+
4849+
SDValue ArgNode = getValue(V);
4850+
Entry.Node = ArgNode; Entry.Ty = V->getType();
48324851

48334852
unsigned attrInd = i - CS.arg_begin() + 1;
48344853
Entry.isSExt = CS.paramHasAttr(attrInd, Attribute::SExt);
@@ -6498,6 +6517,10 @@ SelectionDAGBuilder::HandlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB) {
64986517
// Ignore dead phi's.
64996518
if (PN->use_empty()) continue;
65006519

6520+
// Skip empty types
6521+
if (PN->getType()->isEmptyTy())
6522+
continue;
6523+
65016524
unsigned Reg;
65026525
const Value *PHIOp = PN->getIncomingValueForBlock(LLVMBB);
65036526

llvm/lib/VMCore/Type.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,25 @@ bool Type::canLosslesslyBitCastTo(const Type *Ty) const {
197197
return false; // Other types have no identity values
198198
}
199199

200+
bool Type::isEmptyTy() const {
201+
const ArrayType *ATy = dyn_cast<ArrayType>(this);
202+
if (ATy) {
203+
unsigned NumElements = ATy->getNumElements();
204+
return NumElements == 0 || ATy->getElementType()->isEmptyTy();
205+
}
206+
207+
const StructType *STy = dyn_cast<StructType>(this);
208+
if (STy) {
209+
unsigned NumElements = STy->getNumElements();
210+
for (unsigned i = 0; i < NumElements; ++i)
211+
if (!STy->getElementType(i)->isEmptyTy())
212+
return false;
213+
return true;
214+
}
215+
216+
return false;
217+
}
218+
200219
unsigned Type::getPrimitiveSizeInBits() const {
201220
switch (getTypeID()) {
202221
case Type::FloatTyID: return 32;
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
; RUN: llc < %s
2+
; PR9900
3+
4+
%zero = type [0 x i8]
5+
%foobar = type { i32, %zero }
6+
7+
define void @f(%foobar %arg) {
8+
%arg1 = extractvalue %foobar %arg, 0
9+
%arg2 = extractvalue %foobar %arg, 1
10+
call i32 @f2(%zero %arg2, i32 5, i32 42)
11+
ret void
12+
}
13+
14+
define i32 @f2(%zero %x, i32 %y, i32 %z) {
15+
ret i32 %y
16+
}
17+
18+
define void @f3(%zero %x, i32 %y) {
19+
call i32 @f2(%zero %x, i32 5, i32 %y)
20+
ret void
21+
}
22+
23+
define void @f4(%zero %z) {
24+
insertvalue %foobar undef, %zero %z, 1
25+
ret void
26+
}
27+
28+
define void @f5(%foobar %x) {
29+
allocas:
30+
%y = extractvalue %foobar %x, 1
31+
br label %b1
32+
33+
b1:
34+
%insert120 = insertvalue %foobar undef, %zero %y, 1
35+
ret void
36+
}
37+
38+
define void @f6(%zero %x, %zero %y) {
39+
b1:
40+
br i1 undef, label %end, label %b2
41+
42+
b2:
43+
br label %end
44+
45+
end:
46+
%z = phi %zero [ %y, %b1 ], [ %x, %b2 ]
47+
call void @f4(%zero %z)
48+
ret void
49+
}
50+
51+
%zero2 = type {}
52+
53+
define i32 @g1(%zero2 %x, i32 %y, i32 %z) {
54+
ret i32 %y
55+
}
56+
57+
define void @g2(%zero2 %x, i32 %y) {
58+
call i32 @g1(%zero2 %x, i32 5, i32 %y)
59+
ret void
60+
}
61+
62+
%zero2r = type {%zero2}
63+
64+
define i32 @h1(%zero2r %x, i32 %y, i32 %z) {
65+
ret i32 %y
66+
}
67+
68+
define void @h2(%zero2r %x, i32 %y) {
69+
call i32 @h1(%zero2r %x, i32 5, i32 %y)
70+
ret void
71+
}
72+
73+
%foobar2 = type { i32, %zero2r }
74+
75+
define void @h3(%foobar2 %arg) {
76+
%arg1 = extractvalue %foobar2 %arg, 0
77+
%arg2 = extractvalue %foobar2 %arg, 1
78+
%arg21 = extractvalue %zero2r %arg2, 0
79+
call void @g2(%zero2 %arg21, i32 5)
80+
ret void
81+
}

0 commit comments

Comments
 (0)