Skip to content

Commit 027d9f9

Browse files
author
Evan Cheng
committed
Fix some sub-reg coalescing bugs where the coalescer wasn't updating the resulting interval's register class.
llvm-svn: 76458
1 parent 2aa1a2a commit 027d9f9

File tree

4 files changed

+253
-34
lines changed

4 files changed

+253
-34
lines changed

llvm/lib/CodeGen/SimpleRegisterCoalescing.cpp

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -614,15 +614,17 @@ bool SimpleRegisterCoalescing::ReMaterializeTrivialDef(LiveInterval &SrcInt,
614614
return false;
615615
if (TID.getNumDefs() != 1)
616616
return false;
617-
// Make sure the copy destination register class fits the instruction
618-
// definition register class. The mismatch can happen as a result of earlier
619-
// extract_subreg, insert_subreg, subreg_to_reg coalescing.
620-
const TargetRegisterClass *RC = getInstrOperandRegClass(tri_, TID, 0);
621-
if (TargetRegisterInfo::isVirtualRegister(DstReg)) {
622-
if (mri_->getRegClass(DstReg) != RC)
617+
if (DefMI->getOpcode() != TargetInstrInfo::IMPLICIT_DEF) {
618+
// Make sure the copy destination register class fits the instruction
619+
// definition register class. The mismatch can happen as a result of earlier
620+
// extract_subreg, insert_subreg, subreg_to_reg coalescing.
621+
const TargetRegisterClass *RC = getInstrOperandRegClass(tri_, TID, 0);
622+
if (TargetRegisterInfo::isVirtualRegister(DstReg)) {
623+
if (mri_->getRegClass(DstReg) != RC)
624+
return false;
625+
} else if (!RC->contains(DstReg))
623626
return false;
624-
} else if (!RC->contains(DstReg))
625-
return false;
627+
}
626628

627629
unsigned DefIdx = li_->getDefIndex(CopyIdx);
628630
const LiveRange *DLR= li_->getInterval(DstReg).getLiveRangeContaining(DefIdx);
@@ -1378,13 +1380,17 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {
13781380
}
13791381
}
13801382
if (SubIdx) {
1381-
if (isInsSubReg || isSubRegToReg) {
1382-
if (!DstIsPhys && !SrcIsPhys) {
1383+
if (!DstIsPhys && !SrcIsPhys) {
1384+
if (isInsSubReg || isSubRegToReg) {
13831385
NewRC = tri_->getMatchingSuperRegClass(DstRC, SrcRC, SubIdx);
1384-
if (!NewRC)
1385-
return false;
1386+
} else // extract_subreg {
1387+
NewRC = tri_->getMatchingSuperRegClass(SrcRC, DstRC, SubIdx);
13861388
}
1389+
if (!NewRC) {
1390+
DOUT << "\t Conflicting sub-register indices.\n";
1391+
return false; // Not coalescable
13871392
}
1393+
13881394
unsigned LargeReg = isExtSubReg ? SrcReg : DstReg;
13891395
unsigned SmallReg = isExtSubReg ? DstReg : SrcReg;
13901396
unsigned Limit= allocatableRCRegs_[mri_->getRegClass(SmallReg)].count();

llvm/lib/Target/X86/X86RegisterInfo.cpp

Lines changed: 37 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -161,69 +161,84 @@ X86RegisterInfo::getMatchingSuperRegClass(const TargetRegisterClass *A,
161161
case 1:
162162
// 8-bit
163163
if (B == &X86::GR8RegClass) {
164-
if (A == &X86::GR64RegClass)
165-
return &X86::GR64RegClass;
166-
else if (A == &X86::GR32RegClass)
167-
return &X86::GR32RegClass;
168-
else if (A == &X86::GR16RegClass)
169-
return &X86::GR16RegClass;
164+
if (A->getSize() == 2 || A->getSize() == 4 || A->getSize() == 8)
165+
return A;
170166
} else if (B == &X86::GR8_ABCD_LRegClass || B == &X86::GR8_ABCD_HRegClass) {
171-
if (A == &X86::GR64RegClass || A == &X86::GR64_ABCDRegClass)
167+
if (A == &X86::GR64RegClass || A == &X86::GR64_ABCDRegClass ||
168+
A == &X86::GR64_NOREXRegClass)
172169
return &X86::GR64_ABCDRegClass;
173-
else if (A == &X86::GR32RegClass || A == &X86::GR32_ABCDRegClass)
170+
else if (A == &X86::GR32RegClass || A == &X86::GR32_ABCDRegClass ||
171+
A == &X86::GR32_NOREXRegClass)
174172
return &X86::GR32_ABCDRegClass;
175-
else if (A == &X86::GR16RegClass || A == &X86::GR16_ABCDRegClass)
173+
else if (A == &X86::GR16RegClass || A == &X86::GR16_ABCDRegClass ||
174+
A == &X86::GR16_NOREXRegClass)
176175
return &X86::GR16_ABCDRegClass;
177176
} else if (B == &X86::GR8_NOREXRegClass) {
178177
if (A == &X86::GR64RegClass || A == &X86::GR64_NOREXRegClass)
179178
return &X86::GR64_NOREXRegClass;
179+
else if (A == &X86::GR64_ABCDRegClass)
180+
return &X86::GR64_ABCDRegClass;
180181
else if (A == &X86::GR32RegClass || A == &X86::GR32_NOREXRegClass)
181182
return &X86::GR32_NOREXRegClass;
183+
else if (A == &X86::GR32_ABCDRegClass)
184+
return &X86::GR32_ABCDRegClass;
182185
else if (A == &X86::GR16RegClass || A == &X86::GR16_NOREXRegClass)
183186
return &X86::GR16_NOREXRegClass;
187+
else if (A == &X86::GR16_ABCDRegClass)
188+
return &X86::GR16_ABCDRegClass;
184189
}
185190
break;
186191
case 2:
187192
// 8-bit hi
188193
if (B == &X86::GR8_ABCD_HRegClass) {
189-
if (A == &X86::GR64RegClass || A == &X86::GR64_ABCDRegClass)
194+
if (A == &X86::GR64RegClass || A == &X86::GR64_ABCDRegClass ||
195+
A == &X86::GR64_NOREXRegClass)
190196
return &X86::GR64_ABCDRegClass;
191-
else if (A == &X86::GR32RegClass || A == &X86::GR32_ABCDRegClass)
197+
else if (A == &X86::GR32RegClass || A == &X86::GR32_ABCDRegClass ||
198+
A == &X86::GR32_NOREXRegClass)
192199
return &X86::GR32_ABCDRegClass;
193-
else if (A == &X86::GR16RegClass || A == &X86::GR16_ABCDRegClass)
200+
else if (A == &X86::GR16RegClass || A == &X86::GR16_ABCDRegClass ||
201+
A == &X86::GR16_NOREXRegClass)
194202
return &X86::GR16_ABCDRegClass;
195203
}
196204
break;
197205
case 3:
198206
// 16-bit
199207
if (B == &X86::GR16RegClass) {
200-
if (A == &X86::GR64RegClass)
201-
return &X86::GR64RegClass;
202-
else if (A == &X86::GR32RegClass)
203-
return &X86::GR32RegClass;
208+
if (A->getSize() == 4 || A->getSize() == 8)
209+
return A;
204210
} else if (B == &X86::GR16_ABCDRegClass) {
205-
if (A == &X86::GR64RegClass || A == &X86::GR64_ABCDRegClass)
211+
if (A == &X86::GR64RegClass || A == &X86::GR64_ABCDRegClass ||
212+
A == &X86::GR64_NOREXRegClass)
206213
return &X86::GR64_ABCDRegClass;
207-
else if (A == &X86::GR32RegClass || A == &X86::GR32_ABCDRegClass)
214+
else if (A == &X86::GR32RegClass || A == &X86::GR32_ABCDRegClass ||
215+
A == &X86::GR32_NOREXRegClass)
208216
return &X86::GR32_ABCDRegClass;
209217
} else if (B == &X86::GR16_NOREXRegClass) {
210218
if (A == &X86::GR64RegClass || A == &X86::GR64_NOREXRegClass)
211219
return &X86::GR64_NOREXRegClass;
212-
else if (A == &X86::GR64RegClass || A == &X86::GR64_ABCDRegClass)
220+
else if (A == &X86::GR64_ABCDRegClass)
221+
return &X86::GR64_ABCDRegClass;
222+
else if (A == &X86::GR32RegClass || A == &X86::GR32_NOREXRegClass)
223+
return &X86::GR32_NOREXRegClass;
224+
else if (A == &X86::GR32_ABCDRegClass)
213225
return &X86::GR64_ABCDRegClass;
214226
}
215227
break;
216228
case 4:
217229
// 32-bit
218230
if (B == &X86::GR32RegClass) {
219-
if (A == &X86::GR64RegClass)
220-
return &X86::GR64RegClass;
231+
if (A->getSize() == 8)
232+
return A;
221233
} else if (B == &X86::GR32_ABCDRegClass) {
222-
if (A == &X86::GR64RegClass || A == &X86::GR64_ABCDRegClass)
234+
if (A == &X86::GR64RegClass || A == &X86::GR64_ABCDRegClass ||
235+
A == &X86::GR64_NOREXRegClass)
223236
return &X86::GR64_ABCDRegClass;
224237
} else if (B == &X86::GR32_NOREXRegClass) {
225238
if (A == &X86::GR64RegClass || A == &X86::GR64_NOREXRegClass)
226239
return &X86::GR64_NOREXRegClass;
240+
else if (A == &X86::GR64_ABCDRegClass)
241+
return &X86::GR64_ABCDRegClass;
227242
}
228243
break;
229244
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
; RUN: llvm-as < %s | llc -mtriple=thumbv6-elf | not grep "subs sp"
2+
; PR4567
3+
4+
define arm_apcscc i8* @__gets_chk(i8* %s, i32 %slen) nounwind {
5+
entry:
6+
br i1 undef, label %bb, label %bb1
7+
8+
bb: ; preds = %entry
9+
ret i8* undef
10+
11+
bb1: ; preds = %entry
12+
br i1 undef, label %bb3, label %bb2
13+
14+
bb2: ; preds = %bb1
15+
%0 = alloca i8, i32 undef, align 4 ; <i8*> [#uses=0]
16+
br label %bb4
17+
18+
bb3: ; preds = %bb1
19+
%1 = malloc i8, i32 undef ; <i8*> [#uses=0]
20+
br label %bb4
21+
22+
bb4: ; preds = %bb3, %bb2
23+
br i1 undef, label %bb5, label %bb6
24+
25+
bb5: ; preds = %bb4
26+
%2 = call arm_apcscc i8* @gets(i8* %s) nounwind ; <i8*> [#uses=1]
27+
ret i8* %2
28+
29+
bb6: ; preds = %bb4
30+
unreachable
31+
}
32+
33+
declare arm_apcscc i8* @gets(i8*) nounwind
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
; RUN: llvm-as < %s | llc -mtriple=x86_64-apple-darwin10
2+
; PR4587
3+
; rdar://7072590
4+
5+
%struct.re_pattern_buffer = type <{ i8*, i64, i64, i64, i8*, i64, i64, i8, i8, i8, i8, i8, i8, i8, i8 }>
6+
7+
define fastcc i32 @regex_compile(i8* %pattern, i64 %size, i64 %syntax, %struct.re_pattern_buffer* nocapture %bufp) nounwind ssp {
8+
entry:
9+
br i1 undef, label %return, label %if.end
10+
11+
if.end: ; preds = %entry
12+
%tmp35 = getelementptr %struct.re_pattern_buffer* %bufp, i64 0, i32 3 ; <i64*> [#uses=1]
13+
store i64 %syntax, i64* %tmp35
14+
store i32 undef, i32* undef
15+
br i1 undef, label %if.then66, label %if.end102
16+
17+
if.then66: ; preds = %if.end
18+
br i1 false, label %if.else, label %if.then70
19+
20+
if.then70: ; preds = %if.then66
21+
%call74 = call i8* @xrealloc(i8* undef, i64 32) nounwind ssp ; <i8*> [#uses=0]
22+
unreachable
23+
24+
if.else: ; preds = %if.then66
25+
br i1 false, label %do.body86, label %if.end99
26+
27+
do.body86: ; preds = %if.else
28+
br i1 false, label %do.end, label %if.then90
29+
30+
if.then90: ; preds = %do.body86
31+
unreachable
32+
33+
do.end: ; preds = %do.body86
34+
ret i32 12
35+
36+
if.end99: ; preds = %if.else
37+
br label %if.end102
38+
39+
if.end102: ; preds = %if.end99, %if.end
40+
br label %while.body
41+
42+
while.body: ; preds = %if.end1126, %sw.bb532, %while.body, %if.end102
43+
%laststart.2 = phi i8* [ null, %if.end102 ], [ %laststart.7.ph, %if.end1126 ], [ %laststart.2, %sw.bb532 ], [ %laststart.2, %while.body ] ; <i8*> [#uses=6]
44+
%b.1 = phi i8* [ undef, %if.end102 ], [ %ctg29688, %if.end1126 ], [ %b.1, %sw.bb532 ], [ %b.1, %while.body ] ; <i8*> [#uses=5]
45+
br i1 undef, label %while.body, label %if.end127
46+
47+
if.end127: ; preds = %while.body
48+
switch i32 undef, label %sw.bb532 [
49+
i32 123, label %handle_interval
50+
i32 92, label %do.body3527
51+
]
52+
53+
sw.bb532: ; preds = %if.end127
54+
br i1 undef, label %while.body, label %if.end808
55+
56+
if.end808: ; preds = %sw.bb532
57+
br i1 undef, label %while.cond1267.preheader, label %if.then811
58+
59+
while.cond1267.preheader: ; preds = %if.end808
60+
br i1 false, label %return, label %if.end1294
61+
62+
if.then811: ; preds = %if.end808
63+
%call817 = call fastcc i8* @skip_one_char(i8* %laststart.2) ssp ; <i8*> [#uses=0]
64+
br i1 undef, label %cond.end834, label %lor.lhs.false827
65+
66+
lor.lhs.false827: ; preds = %if.then811
67+
br label %cond.end834
68+
69+
cond.end834: ; preds = %lor.lhs.false827, %if.then811
70+
br i1 undef, label %land.lhs.true838, label %while.cond979.preheader
71+
72+
land.lhs.true838: ; preds = %cond.end834
73+
br i1 undef, label %if.then842, label %while.cond979.preheader
74+
75+
if.then842: ; preds = %land.lhs.true838
76+
%conv851 = trunc i64 undef to i32 ; <i32> [#uses=1]
77+
br label %while.cond979.preheader
78+
79+
while.cond979.preheader: ; preds = %if.then842, %land.lhs.true838, %cond.end834
80+
%startoffset.0.ph = phi i32 [ 0, %cond.end834 ], [ 0, %land.lhs.true838 ], [ %conv851, %if.then842 ] ; <i32> [#uses=2]
81+
%laststart.7.ph = phi i8* [ %laststart.2, %cond.end834 ], [ %laststart.2, %land.lhs.true838 ], [ %laststart.2, %if.then842 ] ; <i8*> [#uses=3]
82+
%b.4.ph = phi i8* [ %b.1, %cond.end834 ], [ %b.1, %land.lhs.true838 ], [ %b.1, %if.then842 ] ; <i8*> [#uses=3]
83+
%ctg29688 = getelementptr i8* %b.4.ph, i64 6 ; <i8*> [#uses=1]
84+
br label %while.cond979
85+
86+
while.cond979: ; preds = %if.end1006, %while.cond979.preheader
87+
%cmp991 = icmp ugt i64 undef, 0 ; <i1> [#uses=1]
88+
br i1 %cmp991, label %do.body994, label %while.end1088
89+
90+
do.body994: ; preds = %while.cond979
91+
br i1 undef, label %return, label %if.end1006
92+
93+
if.end1006: ; preds = %do.body994
94+
%cmp1014 = icmp ugt i64 undef, 32768 ; <i1> [#uses=1]
95+
%storemerge10953 = select i1 %cmp1014, i64 32768, i64 undef ; <i64> [#uses=1]
96+
store i64 %storemerge10953, i64* undef
97+
br i1 false, label %return, label %while.cond979
98+
99+
while.end1088: ; preds = %while.cond979
100+
br i1 undef, label %if.then1091, label %if.else1101
101+
102+
if.then1091: ; preds = %while.end1088
103+
store i8 undef, i8* undef
104+
%idx.ext1132.pre = zext i32 %startoffset.0.ph to i64 ; <i64> [#uses=1]
105+
%add.ptr1133.pre = getelementptr i8* %laststart.7.ph, i64 %idx.ext1132.pre ; <i8*> [#uses=1]
106+
%sub.ptr.lhs.cast1135.pre = ptrtoint i8* %add.ptr1133.pre to i64 ; <i64> [#uses=1]
107+
br label %if.end1126
108+
109+
if.else1101: ; preds = %while.end1088
110+
%cond1109 = select i1 undef, i32 18, i32 14 ; <i32> [#uses=1]
111+
%idx.ext1112 = zext i32 %startoffset.0.ph to i64 ; <i64> [#uses=1]
112+
%add.ptr1113 = getelementptr i8* %laststart.7.ph, i64 %idx.ext1112 ; <i8*> [#uses=2]
113+
%sub.ptr.rhs.cast1121 = ptrtoint i8* %add.ptr1113 to i64 ; <i64> [#uses=1]
114+
call fastcc void @insert_op1(i32 %cond1109, i8* %add.ptr1113, i32 undef, i8* %b.4.ph) ssp
115+
br label %if.end1126
116+
117+
if.end1126: ; preds = %if.else1101, %if.then1091
118+
%sub.ptr.lhs.cast1135.pre-phi = phi i64 [ %sub.ptr.rhs.cast1121, %if.else1101 ], [ %sub.ptr.lhs.cast1135.pre, %if.then1091 ] ; <i64> [#uses=1]
119+
%add.ptr1128 = getelementptr i8* %b.4.ph, i64 3 ; <i8*> [#uses=1]
120+
%sub.ptr.rhs.cast1136 = ptrtoint i8* %add.ptr1128 to i64 ; <i64> [#uses=1]
121+
%sub.ptr.sub1137 = sub i64 %sub.ptr.lhs.cast1135.pre-phi, %sub.ptr.rhs.cast1136 ; <i64> [#uses=1]
122+
%sub.ptr.sub11378527 = trunc i64 %sub.ptr.sub1137 to i32 ; <i32> [#uses=1]
123+
%conv1139 = add i32 %sub.ptr.sub11378527, -3 ; <i32> [#uses=1]
124+
store i8 undef, i8* undef
125+
%shr10.i8599 = lshr i32 %conv1139, 8 ; <i32> [#uses=1]
126+
%conv6.i8600 = trunc i32 %shr10.i8599 to i8 ; <i8> [#uses=1]
127+
store i8 %conv6.i8600, i8* undef
128+
br label %while.body
129+
130+
if.end1294: ; preds = %while.cond1267.preheader
131+
ret i32 12
132+
133+
do.body3527: ; preds = %if.end127
134+
br i1 undef, label %do.end3536, label %if.then3531
135+
136+
if.then3531: ; preds = %do.body3527
137+
unreachable
138+
139+
do.end3536: ; preds = %do.body3527
140+
ret i32 5
141+
142+
handle_interval: ; preds = %if.end127
143+
br i1 undef, label %do.body4547, label %cond.false4583
144+
145+
do.body4547: ; preds = %handle_interval
146+
br i1 undef, label %do.end4556, label %if.then4551
147+
148+
if.then4551: ; preds = %do.body4547
149+
unreachable
150+
151+
do.end4556: ; preds = %do.body4547
152+
ret i32 9
153+
154+
cond.false4583: ; preds = %handle_interval
155+
unreachable
156+
157+
return: ; preds = %if.end1006, %do.body994, %while.cond1267.preheader, %entry
158+
ret i32 undef
159+
}
160+
161+
declare i8* @xrealloc(i8*, i64) ssp
162+
163+
declare fastcc i8* @skip_one_char(i8*) nounwind readonly ssp
164+
165+
declare fastcc void @insert_op1(i32, i8*, i32, i8*) nounwind ssp

0 commit comments

Comments
 (0)