[llvm] [InstCombine] Compare `icmp inttoptr, inttoptr` values directly (PR #107012)
Marina Taylor via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 6 04:11:20 PDT 2024
https://github.com/citymarina updated https://github.com/llvm/llvm-project/pull/107012
>From 919852cd07e452db923077297f81ea4fa66a6240 Mon Sep 17 00:00:00 2001
From: Marina Taylor <marina_taylor at apple.com>
Date: Fri, 6 Sep 2024 11:47:32 +0100
Subject: [PATCH 1/2] [InstCombine] Add tests for fold of `icmp inttoptr,
inttoptr`. NFC
---
.../Transforms/InstCombine/icmp-inttoptr.ll | 110 ++++++++++++++++++
1 file changed, 110 insertions(+)
create mode 100644 llvm/test/Transforms/InstCombine/icmp-inttoptr.ll
diff --git a/llvm/test/Transforms/InstCombine/icmp-inttoptr.ll b/llvm/test/Transforms/InstCombine/icmp-inttoptr.ll
new file mode 100644
index 00000000000000..21ffca0c85db6b
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/icmp-inttoptr.ll
@@ -0,0 +1,110 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -passes=instcombine -S | FileCheck %s
+
+target datalayout = "e-p:64:64:64-p1:16:16:16-p2:32:32:32-p3:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+
+declare void @use_ptr(ptr)
+
+define i1 @inttoptr(i64 %x, i64 %y) {
+; CHECK-LABEL: @inttoptr(
+; CHECK-NEXT: [[XPTR:%.*]] = inttoptr i64 [[X:%.*]] to ptr
+; CHECK-NEXT: [[YPTR:%.*]] = inttoptr i64 [[Y:%.*]] to ptr
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[XPTR]], [[YPTR]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %xptr = inttoptr i64 %x to ptr
+ %yptr = inttoptr i64 %y to ptr
+ %cmp = icmp eq ptr %xptr, %yptr
+ ret i1 %cmp
+}
+
+define i1 @inttoptr_constant(i64 %x) {
+; CHECK-LABEL: @inttoptr_constant(
+; CHECK-NEXT: [[XPTR:%.*]] = inttoptr i64 [[X:%.*]] to ptr
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[XPTR]], inttoptr (i64 42 to ptr)
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %xptr = inttoptr i64 %x to ptr
+ %cmp = icmp eq ptr %xptr, inttoptr (i64 42 to ptr)
+ ret i1 %cmp
+}
+
+define <2 x i1> @inttoptr_vector(<2 x i64> %x, <2 x i64> %y) {
+; CHECK-LABEL: @inttoptr_vector(
+; CHECK-NEXT: [[XPTR:%.*]] = inttoptr <2 x i64> [[X:%.*]] to <2 x ptr>
+; CHECK-NEXT: [[YPTR:%.*]] = inttoptr <2 x i64> [[Y:%.*]] to <2 x ptr>
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x ptr> [[XPTR]], [[YPTR]]
+; CHECK-NEXT: ret <2 x i1> [[CMP]]
+;
+ %xptr = inttoptr <2 x i64> %x to <2 x ptr>
+ %yptr = inttoptr <2 x i64> %y to <2 x ptr>
+ %cmp = icmp eq <2 x ptr> %xptr, %yptr
+ ret <2 x i1> %cmp
+}
+
+define <2 x i1> @inttoptr_vector_constant(<2 x i64> %x) {
+; CHECK-LABEL: @inttoptr_vector_constant(
+; CHECK-NEXT: [[XPTR:%.*]] = inttoptr <2 x i64> [[X:%.*]] to <2 x ptr>
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x ptr> [[XPTR]], <ptr inttoptr (i64 42 to ptr), ptr inttoptr (i64 123 to ptr)>
+; CHECK-NEXT: ret <2 x i1> [[CMP]]
+;
+ %xptr = inttoptr <2 x i64> %x to <2 x ptr>
+ %cmp = icmp eq <2 x ptr> %xptr, inttoptr (<2 x i64> <i64 42, i64 123> to <2 x ptr>)
+ ret <2 x i1> %cmp
+}
+
+define i1 @inttoptr_size_mismatch(i200 %x, i9 %y) {
+; CHECK-LABEL: @inttoptr_size_mismatch(
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i200 [[X:%.*]] to i64
+; CHECK-NEXT: [[XPTR:%.*]] = inttoptr i64 [[TMP1]] to ptr
+; CHECK-NEXT: [[TMP2:%.*]] = zext i9 [[Y:%.*]] to i64
+; CHECK-NEXT: [[YPTR:%.*]] = inttoptr i64 [[TMP2]] to ptr
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[XPTR]], [[YPTR]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %xptr = inttoptr i200 %x to ptr
+ %yptr = inttoptr i9 %y to ptr
+ %cmp = icmp eq ptr %xptr, %yptr
+ ret i1 %cmp
+}
+
+define <2 x i1> @inttoptr_vector_constant_size_mismatch(<2 x i200> %x) {
+; CHECK-LABEL: @inttoptr_vector_constant_size_mismatch(
+; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i200> [[X:%.*]] to <2 x i64>
+; CHECK-NEXT: [[XPTR:%.*]] = inttoptr <2 x i64> [[TMP1]] to <2 x ptr>
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x ptr> [[XPTR]], <ptr inttoptr (i9 42 to ptr), ptr inttoptr (i9 123 to ptr)>
+; CHECK-NEXT: ret <2 x i1> [[CMP]]
+;
+ %xptr = inttoptr <2 x i200> %x to <2 x ptr>
+ %cmp = icmp eq <2 x ptr> %xptr, inttoptr (<2x i9> <i9 42, i9 123> to <2 x ptr>)
+ ret <2 x i1> %cmp
+}
+
+define i1 @inttoptr_oneside(i64 %x, ptr %y) {
+; CHECK-LABEL: @inttoptr_oneside(
+; CHECK-NEXT: [[XPTR:%.*]] = inttoptr i64 [[X:%.*]] to ptr
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[Y:%.*]], [[XPTR]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %xptr = inttoptr i64 %x to ptr
+ %cmp = icmp eq ptr %xptr, %y
+ ret i1 %cmp
+}
+
+define i1 @inttoptr_used(i64 %x, i64 %y) {
+; CHECK-LABEL: @inttoptr_used(
+; CHECK-NEXT: [[XPTR:%.*]] = inttoptr i64 [[X:%.*]] to ptr
+; CHECK-NEXT: [[YPTR:%.*]] = inttoptr i64 [[Y:%.*]] to ptr
+; CHECK-NEXT: call void @use_ptr(ptr [[XPTR]])
+; CHECK-NEXT: call void @use_ptr(ptr [[YPTR]])
+; CHECK-NEXT: [[CMP:%.*]] = icmp ugt ptr [[XPTR]], [[YPTR]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %xptr = inttoptr i64 %x to ptr
+ %yptr = inttoptr i64 %y to ptr
+ call void @use_ptr(ptr %xptr)
+ call void @use_ptr(ptr %yptr)
+ %cmp = icmp ugt ptr %xptr, %yptr
+ ret i1 %cmp
+}
+
>From b5db1ab4b68baa492bab99d66b632f25b061f282 Mon Sep 17 00:00:00 2001
From: Marina Taylor <marina_taylor at apple.com>
Date: Fri, 6 Sep 2024 12:02:46 +0100
Subject: [PATCH 2/2] [InstCombine] Compare icmp inttoptr, inttoptr values
directly
InstCombine already has some rules for `icmp ptrtoint, ptrtoint` to
drop the casts and compare the source values. This change adds the
same for the reverse case with `inttoptr`.
---
.../InstCombine/InstCombineCompares.cpp | 26 +++++++++++++++----
.../Transforms/InstCombine/icmp-inttoptr.ll | 25 ++++++------------
2 files changed, 29 insertions(+), 22 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 8e8d472a5df1d3..af60b1886fc72e 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -6081,12 +6081,12 @@ Instruction *InstCombinerImpl::foldICmpWithCastOp(ICmpInst &ICmp) {
// Turn icmp (ptrtoint x), (ptrtoint/c) into a compare of the input if the
// integer type is the same size as the pointer type.
- auto CompatibleSizes = [&](Type *SrcTy, Type *DestTy) {
- if (isa<VectorType>(SrcTy)) {
- SrcTy = cast<VectorType>(SrcTy)->getElementType();
- DestTy = cast<VectorType>(DestTy)->getElementType();
+ auto CompatibleSizes = [&](Type *PtrTy, Type *IntTy) {
+ if (isa<VectorType>(PtrTy)) {
+ PtrTy = cast<VectorType>(PtrTy)->getElementType();
+ IntTy = cast<VectorType>(IntTy)->getElementType();
}
- return DL.getPointerTypeSizeInBits(SrcTy) == DestTy->getIntegerBitWidth();
+ return DL.getPointerTypeSizeInBits(PtrTy) == IntTy->getIntegerBitWidth();
};
if (CastOp0->getOpcode() == Instruction::PtrToInt &&
CompatibleSizes(SrcTy, DestTy)) {
@@ -6103,6 +6103,22 @@ Instruction *InstCombinerImpl::foldICmpWithCastOp(ICmpInst &ICmp) {
return new ICmpInst(ICmp.getPredicate(), Op0Src, NewOp1);
}
+ // Do the same in the other direction for icmp (inttoptr x), (inttoptr/c).
+ if (CastOp0->getOpcode() == Instruction::IntToPtr &&
+ CompatibleSizes(DestTy, SrcTy)) {
+ Value *NewOp1 = nullptr;
+ if (auto *IntToPtrOp1 = dyn_cast<IntToPtrInst>(ICmp.getOperand(1))) {
+ Value *IntSrc = IntToPtrOp1->getOperand(0);
+ if (IntSrc->getType() == Op0Src->getType())
+ NewOp1 = IntToPtrOp1->getOperand(0);
+ } else if (auto *RHSC = dyn_cast<Constant>(ICmp.getOperand(1))) {
+ NewOp1 = ConstantExpr::getPtrToInt(RHSC, SrcTy);
+ }
+
+ if (NewOp1)
+ return new ICmpInst(ICmp.getPredicate(), Op0Src, NewOp1);
+ }
+
if (Instruction *R = foldICmpWithTrunc(ICmp))
return R;
diff --git a/llvm/test/Transforms/InstCombine/icmp-inttoptr.ll b/llvm/test/Transforms/InstCombine/icmp-inttoptr.ll
index 21ffca0c85db6b..cff5a88553d321 100644
--- a/llvm/test/Transforms/InstCombine/icmp-inttoptr.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-inttoptr.ll
@@ -1,5 +1,5 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt < %s -passes=instcombine -S | FileCheck %s
+; RUN: opt < %s -passes='instcombine<max-iterations=2>' -S | FileCheck %s
target datalayout = "e-p:64:64:64-p1:16:16:16-p2:32:32:32-p3:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
@@ -7,9 +7,7 @@ declare void @use_ptr(ptr)
define i1 @inttoptr(i64 %x, i64 %y) {
; CHECK-LABEL: @inttoptr(
-; CHECK-NEXT: [[XPTR:%.*]] = inttoptr i64 [[X:%.*]] to ptr
-; CHECK-NEXT: [[YPTR:%.*]] = inttoptr i64 [[Y:%.*]] to ptr
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[XPTR]], [[YPTR]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: ret i1 [[CMP]]
;
%xptr = inttoptr i64 %x to ptr
@@ -20,8 +18,7 @@ define i1 @inttoptr(i64 %x, i64 %y) {
define i1 @inttoptr_constant(i64 %x) {
; CHECK-LABEL: @inttoptr_constant(
-; CHECK-NEXT: [[XPTR:%.*]] = inttoptr i64 [[X:%.*]] to ptr
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[XPTR]], inttoptr (i64 42 to ptr)
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[X:%.*]], 42
; CHECK-NEXT: ret i1 [[CMP]]
;
%xptr = inttoptr i64 %x to ptr
@@ -31,9 +28,7 @@ define i1 @inttoptr_constant(i64 %x) {
define <2 x i1> @inttoptr_vector(<2 x i64> %x, <2 x i64> %y) {
; CHECK-LABEL: @inttoptr_vector(
-; CHECK-NEXT: [[XPTR:%.*]] = inttoptr <2 x i64> [[X:%.*]] to <2 x ptr>
-; CHECK-NEXT: [[YPTR:%.*]] = inttoptr <2 x i64> [[Y:%.*]] to <2 x ptr>
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x ptr> [[XPTR]], [[YPTR]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i64> [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
%xptr = inttoptr <2 x i64> %x to <2 x ptr>
@@ -44,8 +39,7 @@ define <2 x i1> @inttoptr_vector(<2 x i64> %x, <2 x i64> %y) {
define <2 x i1> @inttoptr_vector_constant(<2 x i64> %x) {
; CHECK-LABEL: @inttoptr_vector_constant(
-; CHECK-NEXT: [[XPTR:%.*]] = inttoptr <2 x i64> [[X:%.*]] to <2 x ptr>
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x ptr> [[XPTR]], <ptr inttoptr (i64 42 to ptr), ptr inttoptr (i64 123 to ptr)>
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i64> [[X:%.*]], <i64 42, i64 123>
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
%xptr = inttoptr <2 x i64> %x to <2 x ptr>
@@ -56,10 +50,8 @@ define <2 x i1> @inttoptr_vector_constant(<2 x i64> %x) {
define i1 @inttoptr_size_mismatch(i200 %x, i9 %y) {
; CHECK-LABEL: @inttoptr_size_mismatch(
; CHECK-NEXT: [[TMP1:%.*]] = trunc i200 [[X:%.*]] to i64
-; CHECK-NEXT: [[XPTR:%.*]] = inttoptr i64 [[TMP1]] to ptr
; CHECK-NEXT: [[TMP2:%.*]] = zext i9 [[Y:%.*]] to i64
-; CHECK-NEXT: [[YPTR:%.*]] = inttoptr i64 [[TMP2]] to ptr
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[XPTR]], [[YPTR]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[TMP1]], [[TMP2]]
; CHECK-NEXT: ret i1 [[CMP]]
;
%xptr = inttoptr i200 %x to ptr
@@ -71,8 +63,7 @@ define i1 @inttoptr_size_mismatch(i200 %x, i9 %y) {
define <2 x i1> @inttoptr_vector_constant_size_mismatch(<2 x i200> %x) {
; CHECK-LABEL: @inttoptr_vector_constant_size_mismatch(
; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i200> [[X:%.*]] to <2 x i64>
-; CHECK-NEXT: [[XPTR:%.*]] = inttoptr <2 x i64> [[TMP1]] to <2 x ptr>
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x ptr> [[XPTR]], <ptr inttoptr (i9 42 to ptr), ptr inttoptr (i9 123 to ptr)>
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i64> [[TMP1]], <i64 42, i64 123>
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
%xptr = inttoptr <2 x i200> %x to <2 x ptr>
@@ -97,7 +88,7 @@ define i1 @inttoptr_used(i64 %x, i64 %y) {
; CHECK-NEXT: [[YPTR:%.*]] = inttoptr i64 [[Y:%.*]] to ptr
; CHECK-NEXT: call void @use_ptr(ptr [[XPTR]])
; CHECK-NEXT: call void @use_ptr(ptr [[YPTR]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp ugt ptr [[XPTR]], [[YPTR]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i64 [[X]], [[Y]]
; CHECK-NEXT: ret i1 [[CMP]]
;
%xptr = inttoptr i64 %x to ptr
More information about the llvm-commits
mailing list