Skip to content

Commit 2aae304

Browse files
authored
[InstCombine] Fold icmp pred (inttoptr X), (inttoptr Y) -> icmp pred X, Y (#77832)
NOTE: Alive2 proofs are unavailable because `inttoptr` is unsupported.
1 parent d199ab4 commit 2aae304

File tree

2 files changed

+54
-0
lines changed

2 files changed

+54
-0
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5703,6 +5703,15 @@ Instruction *InstCombinerImpl::foldICmpWithCastOp(ICmpInst &ICmp) {
57035703
return new ICmpInst(ICmp.getPredicate(), Op0Src, NewOp1);
57045704
}
57055705

5706+
// Turn icmp pred (inttoptr x), (inttoptr y) into icmp pred x, y
5707+
if (CastOp0->getOpcode() == Instruction::IntToPtr &&
5708+
CompatibleSizes(DestTy, SrcTy)) {
5709+
Value *Op1Src;
5710+
if (match(ICmp.getOperand(1), m_IntToPtr(m_Value(Op1Src))) &&
5711+
Op1Src->getType() == SrcTy)
5712+
return new ICmpInst(ICmp.getPredicate(), Op0Src, Op1Src);
5713+
}
5714+
57065715
if (Instruction *R = foldICmpWithTrunc(ICmp))
57075716
return R;
57085717

llvm/test/Transforms/InstCombine/cast_ptr.ll

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,51 @@ define i1 @test4(i32 %A) {
113113
ret i1 %C
114114
}
115115

116+
define i1 @test4_icmp_with_var(i32 %A1, i32 %A2) {
117+
; CHECK-LABEL: @test4_icmp_with_var(
118+
; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[A1:%.*]], [[A2:%.*]]
119+
; CHECK-NEXT: ret i1 [[C]]
120+
;
121+
%B1 = inttoptr i32 %A1 to ptr
122+
%B2 = inttoptr i32 %A2 to ptr
123+
%C = icmp ugt ptr %B1, %B2
124+
ret i1 %C
125+
}
126+
127+
define i1 @test4_cmp_with_nonnull_constant(i32 %A) {
128+
; CHECK-LABEL: @test4_cmp_with_nonnull_constant(
129+
; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[A:%.*]], 1
130+
; CHECK-NEXT: ret i1 [[C]]
131+
;
132+
%B = inttoptr i32 %A to ptr
133+
%C = icmp eq ptr %B, inttoptr (i32 1 to ptr)
134+
ret i1 %C
135+
}
136+
137+
define i1 @test4_cmp_eq_0_or_1(i32 %x) {
138+
; CHECK-LABEL: @test4_cmp_eq_0_or_1(
139+
; CHECK-NEXT: [[OR:%.*]] = icmp ult i32 [[X:%.*]], 2
140+
; CHECK-NEXT: ret i1 [[OR]]
141+
;
142+
%cast = inttoptr i32 %x to ptr
143+
%tobool = icmp eq i32 %x, 0
144+
%cmp = icmp eq ptr %cast, inttoptr (i32 1 to ptr)
145+
%or = or i1 %tobool, %cmp
146+
ret i1 %or
147+
}
148+
149+
define i1 @test4_icmp_with_var_mismatched_type(i32 %A1, i64 %A2) {
150+
; CHECK-LABEL: @test4_icmp_with_var_mismatched_type(
151+
; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[A2:%.*]] to i32
152+
; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[TMP1]], [[A1:%.*]]
153+
; CHECK-NEXT: ret i1 [[C]]
154+
;
155+
%B1 = inttoptr i32 %A1 to ptr
156+
%B2 = inttoptr i64 %A2 to ptr
157+
%C = icmp ugt ptr %B1, %B2
158+
ret i1 %C
159+
}
160+
116161
define i1 @test4_as2(i16 %A) {
117162
; CHECK-LABEL: @test4_as2(
118163
; CHECK-NEXT: [[C:%.*]] = icmp eq i16 [[A:%.*]], 0

0 commit comments

Comments
 (0)