Skip to content

Commit da9c346

Browse files
committed
Functions with differing phis should not be merged.
Check that the incoming blocks of phi nodes are identical, and block function merging if they are not. rdar://problem/26387654
1 parent ff85686 commit da9c346

File tree

2 files changed

+68
-7
lines changed

2 files changed

+68
-7
lines changed

lib/LLVMPasses/LLVMMergeFunctions.cpp

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -241,11 +241,11 @@ class FunctionComparator {
241241
/// look at their particular properties (bit-width for vectors, and
242242
/// address space for pointers).
243243
/// If these properties are equal - compare their contents.
244-
int cmpConstants(const Constant *L, const Constant *R);
244+
int cmpConstants(const Constant *L, const Constant *R) const;
245245

246246
/// Compares two global values by number. Uses the GlobalNumbersState to
247247
/// identify the same globals across function calls.
248-
int cmpGlobalValues(GlobalValue *L, GlobalValue *R);
248+
int cmpGlobalValues(GlobalValue *L, GlobalValue *R) const;
249249

250250
/// Assign or look up previously assigned numbers for the two values, and
251251
/// return whether the numbers are equal. Numbers are assigned in the order
@@ -265,7 +265,7 @@ class FunctionComparator {
265265
/// then left value is greater.
266266
/// In another words, we compare serial numbers, for more details
267267
/// see comments for sn_mapL and sn_mapR.
268-
int cmpValues(const Value *L, const Value *R);
268+
int cmpValues(const Value *L, const Value *R) const;
269269

270270
/// Compare two Instructions for equivalence, similar to
271271
/// Instruction::isSameOperationAs but with modifications to the type
@@ -395,7 +395,7 @@ class FunctionComparator {
395395
/// But, we are still not able to compare operands of PHI nodes, since those
396396
/// could be operands from further BBs we didn't scan yet.
397397
/// So it's impossible to use dominance properties in general.
398-
DenseMap<const Value*, int> sn_mapL, sn_mapR;
398+
mutable DenseMap<const Value *, int> sn_mapL, sn_mapR;
399399

400400
// The global state we will use
401401
GlobalNumberState* GlobalNumbers;
@@ -528,7 +528,8 @@ int FunctionComparator::cmpOperandBundlesSchema(const Instruction *L,
528528
/// type.
529529
/// 2. Compare constant contents.
530530
/// For more details see declaration comments.
531-
int FunctionComparator::cmpConstants(const Constant *L, const Constant *R) {
531+
int FunctionComparator::cmpConstants(const Constant *L,
532+
const Constant *R) const {
532533

533534
Type *TyL = L->getType();
534535
Type *TyR = R->getType();
@@ -725,7 +726,7 @@ int FunctionComparator::cmpConstants(const Constant *L, const Constant *R) {
725726
}
726727
}
727728

728-
int FunctionComparator::cmpGlobalValues(GlobalValue *L, GlobalValue* R) {
729+
int FunctionComparator::cmpGlobalValues(GlobalValue *L, GlobalValue *R) const {
729730
return cmpNumbers(GlobalNumbers->getNumber(L), GlobalNumbers->getNumber(R));
730731
}
731732

@@ -975,6 +976,17 @@ int FunctionComparator::cmpOperations(const Instruction *L,
975976
return cmpNumbers(RMWI->getSynchScope(),
976977
cast<AtomicRMWInst>(R)->getSynchScope());
977978
}
979+
if (const PHINode *PNL = dyn_cast<PHINode>(L)) {
980+
const PHINode *PNR = cast<PHINode>(R);
981+
// Ensure that in addition to the incoming values being identical
982+
// (checked by the caller of this function), the incoming blocks
983+
// are also identical.
984+
for (unsigned i = 0, e = PNL->getNumIncomingValues(); i != e; ++i) {
985+
if (int Res =
986+
cmpValues(PNL->getIncomingBlock(i), PNR->getIncomingBlock(i)))
987+
return Res;
988+
}
989+
}
978990
return 0;
979991
}
980992

@@ -1038,7 +1050,7 @@ int FunctionComparator::cmpInlineAsm(const InlineAsm *L,
10381050
/// this is the first time the values are seen, they're added to the mapping so
10391051
/// that we will detect mismatches on next use.
10401052
/// See comments in declaration for more details.
1041-
int FunctionComparator::cmpValues(const Value *L, const Value *R) {
1053+
int FunctionComparator::cmpValues(const Value *L, const Value *R) const {
10421054
// Catch self-reference case.
10431055
if (L == FnL) {
10441056
if (R == FnR)

test/LLVMPasses/merge_func.ll

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,3 +274,52 @@ define i32 @caller_b(i32 %x, i32 %y) {
274274
; CHECK: call fastcc i32 @callee1_a_merged(i32 %sum2, i32 %1, i32* %2)
275275
; CHECK: ret
276276

277+
278+
; Ensure that we do not merge functions that are identical with the
279+
; exception of the order of the incoming blocks to a phi.
280+
281+
; CHECK-LABEL: define linkonce_odr hidden i1 @first(i2)
282+
define linkonce_odr hidden i1 @first(i2) {
283+
entry:
284+
; CHECK: switch i2
285+
switch i2 %0, label %default [
286+
i2 0, label %L1
287+
i2 1, label %L2
288+
i2 -2, label %L3
289+
]
290+
default:
291+
unreachable
292+
L1:
293+
br label %done
294+
L2:
295+
br label %done
296+
L3:
297+
br label %done
298+
done:
299+
%result = phi i1 [ true, %L1 ], [ false, %L2 ], [ false, %L3 ]
300+
; CHECK: ret i1
301+
ret i1 %result
302+
}
303+
304+
; CHECK-LABEL: define linkonce_odr hidden i1 @second(i2)
305+
define linkonce_odr hidden i1 @second(i2) {
306+
entry:
307+
; CHECK: switch i2
308+
switch i2 %0, label %default [
309+
i2 0, label %L1
310+
i2 1, label %L2
311+
i2 -2, label %L3
312+
]
313+
default:
314+
unreachable
315+
L1:
316+
br label %done
317+
L2:
318+
br label %done
319+
L3:
320+
br label %done
321+
done:
322+
%result = phi i1 [ true, %L3 ], [ false, %L2 ], [ false, %L1 ]
323+
; CHECK: ret i1
324+
ret i1 %result
325+
}

0 commit comments

Comments
 (0)