Skip to content

Commit 3c0096a

Browse files
committed
[MergeICmps] Don't call comesBefore() if in different blocks (PR53959)
Only call comesBefore() if the instructions are in the same block. Otherwise make a conservative assumption. Fixes #53959.
1 parent 01c0b4d commit 3c0096a

File tree

2 files changed

+49
-1
lines changed

2 files changed

+49
-1
lines changed

llvm/lib/Transforms/Scalar/MergeICmps.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ bool BCECmpBlock::canSinkBCECmpInst(const Instruction *Inst,
244244
auto MayClobber = [&](LoadInst *LI) {
245245
// If a potentially clobbering instruction comes before the load,
246246
// we can still safely sink the load.
247-
return !Inst->comesBefore(LI) &&
247+
return (Inst->getParent() != LI->getParent() || !Inst->comesBefore(LI)) &&
248248
isModSet(AA.getModRefInfo(Inst, MemoryLocation::get(LI)));
249249
};
250250
if (MayClobber(Cmp.Lhs.LoadI) || MayClobber(Cmp.Rhs.LoadI))
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2+
; RUN: opt -S -mergeicmps < %s | FileCheck %s
3+
4+
target triple = "x86_64-unknown-linux-gnu"
5+
6+
@c = external global i32, align 4
7+
8+
define i1 @d() {
9+
; CHECK-LABEL: @d(
10+
; CHECK-NEXT: entry:
11+
; CHECK-NEXT: [[G:%.*]] = alloca [8 x i64], align 16
12+
; CHECK-NEXT: [[IDX1:%.*]] = getelementptr inbounds [8 x i64], [8 x i64]* [[G]], i64 0, i64 0
13+
; CHECK-NEXT: [[V1:%.*]] = load i64, i64* [[IDX1]], align 8
14+
; CHECK-NEXT: [[IDX2:%.*]] = getelementptr inbounds [8 x i64], [8 x i64]* [[G]], i64 0, i64 0
15+
; CHECK-NEXT: [[V2:%.*]] = load i64, i64* [[IDX2]], align 8
16+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[V1]], [[V2]]
17+
; CHECK-NEXT: br label [[SPLIT:%.*]]
18+
; CHECK: split:
19+
; CHECK-NEXT: [[X:%.*]] = load volatile i32, i32* @c, align 4
20+
; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[EXIT:%.*]]
21+
; CHECK: if:
22+
; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[X]], 0
23+
; CHECK-NEXT: br label [[EXIT]]
24+
; CHECK: exit:
25+
; CHECK-NEXT: [[P:%.*]] = phi i1 [ false, [[SPLIT]] ], [ [[TOBOOL]], [[IF]] ]
26+
; CHECK-NEXT: ret i1 [[P]]
27+
;
28+
entry:
29+
%g = alloca [8 x i64], align 16
30+
%idx1 = getelementptr inbounds [8 x i64], [8 x i64]* %g, i64 0, i64 0
31+
%v1 = load i64, i64* %idx1, align 8
32+
%idx2 = getelementptr inbounds [8 x i64], [8 x i64]* %g, i64 0, i64 0
33+
%v2 = load i64, i64* %idx2, align 8
34+
%cmp = icmp eq i64 %v1, %v2
35+
br label %split
36+
37+
split:
38+
%x = load volatile i32, i32* @c, align 4
39+
br i1 %cmp, label %if, label %exit
40+
41+
if:
42+
%tobool = icmp ne i32 %x, 0
43+
br label %exit
44+
45+
exit:
46+
%p = phi i1 [ false, %split ], [ %tobool, %if ]
47+
ret i1 %p
48+
}

0 commit comments

Comments
 (0)