[llvm] [InstCombine] Fold pointer adding in integer to arithmetic add (PR #91596)
via llvm-commits
llvm-commits at lists.llvm.org
Thu May 9 06:58:14 PDT 2024
https://github.com/YanWQ-monad created https://github.com/llvm/llvm-project/pull/91596
Fold
``` llvm
define i32 @src(i32 %x, i32 %y) {
%base = inttoptr i32 %x to ptr
%ptr = getelementptr inbounds i8, ptr %base, i32 %y
%r = ptrtoint ptr %ptr to i32
ret i32 %r
}
```
where both `%base` and `%ptr` have only one use, to
``` llvm
define i32 @tgt(i32 %x, i32 %y) {
%r = add nuw i32 %x, %y
ret i32 %r
}
```
### Motivation
It seems unnecessary to convert `int` to `ptr` just to get its offset. In most cases, they generates the same assembly, but sometimes it may miss some optimizations since the analysis of `GEP` is not as perfect as that of arithmetic operation. One example is
https://github.com/dtcxzyw/llvm-opt-benchmark/blob/e3c822bf41df3a88ca38eba884a52b0cc7e70bf2/bench/protobuf/optimized/generated_message_reflection.cc.ll#L39860-L39873
``` llvm
%conv.i188 = zext i32 %145 to i64
%add.i189 = add i64 %conv.i188, %125
%146 = load i16, ptr %num_aux_entries10.i, align 2
%conv2.i191 = zext i16 %146 to i64
%mul.i192 = shl nuw nsw i64 %conv2.i191, 3
%add3.i193 = add i64 %add.i189, %mul.i192
%147 = inttoptr i64 %add3.i193 to ptr
%sub.ptr.lhs.cast.i195 = ptrtoint ptr %144 to i64
%sub.ptr.rhs.cast.i196 = ptrtoint ptr %143 to i64
%sub.ptr.sub.i197 = sub i64 %sub.ptr.lhs.cast.i195, %sub.ptr.rhs.cast.i196
%add.ptr = getelementptr inbounds i8, ptr %147, i64 %sub.ptr.sub.i197
%sub.ptr.lhs.cast = ptrtoint ptr %add.ptr to i64
%sub.ptr.sub = sub i64 %sub.ptr.lhs.cast, %125
```
where `%conv.i188` first adds `%125` and then subtracts `%125` (the result is `%sub.ptr.sub`), which can be optimized.
But this fold involves `ptr`, which Alive2 can't verify, plus that in most cases, they generate the same assembly, I am not sure whether it is profitable.
>From c33503abc9c7b08f64878ec3c4dcdb1d7b4bc3fb Mon Sep 17 00:00:00 2001
From: YanWQ-monad <YanWQmonad at gmail.com>
Date: Thu, 9 May 2024 20:15:28 +0800
Subject: [PATCH 1/2] [InstCombine] Pre-commit: add tests
---
llvm/test/Transforms/InstCombine/cast_ptr.ll | 58 ++++++++++++++++++++
1 file changed, 58 insertions(+)
diff --git a/llvm/test/Transforms/InstCombine/cast_ptr.ll b/llvm/test/Transforms/InstCombine/cast_ptr.ll
index 5c6c012064e05..185c02fbdafca 100644
--- a/llvm/test/Transforms/InstCombine/cast_ptr.ll
+++ b/llvm/test/Transforms/InstCombine/cast_ptr.ll
@@ -244,3 +244,61 @@ define <2 x i32> @insertelt_extra_use2(<2 x i32> %x, ptr %p) {
%r = ptrtoint <2 x ptr> %i to <2 x i32>
ret <2 x i32> %r
}
+
+define i32 @ptr_add_in_int(i32 %x, i32 %y) {
+; CHECK-LABEL: @ptr_add_in_int(
+; CHECK-NEXT: [[PTR:%.*]] = inttoptr i32 [[X:%.*]] to ptr
+; CHECK-NEXT: [[P2:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i32 [[Y:%.*]]
+; CHECK-NEXT: [[R:%.*]] = ptrtoint ptr [[P2]] to i32
+; CHECK-NEXT: ret i32 [[R]]
+;
+ %ptr = inttoptr i32 %x to ptr
+ %p2 = getelementptr inbounds i8, ptr %ptr, i32 %y
+ %r = ptrtoint ptr %p2 to i32
+ ret i32 %r
+}
+
+define i32 @ptr_add_in_int_const(i32 %x) {
+; CHECK-LABEL: @ptr_add_in_int_const(
+; CHECK-NEXT: [[PTR:%.*]] = inttoptr i32 [[X:%.*]] to ptr
+; CHECK-NEXT: [[P2:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i32 4096
+; CHECK-NEXT: [[R:%.*]] = ptrtoint ptr [[P2]] to i32
+; CHECK-NEXT: ret i32 [[R]]
+;
+ %ptr = inttoptr i32 %x to ptr
+ %p2 = getelementptr inbounds i8, ptr %ptr, i32 4096
+ %r = ptrtoint ptr %p2 to i32
+ ret i32 %r
+}
+
+declare void @use_ptr(ptr)
+
+define i32 @ptr_add_in_int_extra_use1(i32 %x) {
+; CHECK-LABEL: @ptr_add_in_int_extra_use1(
+; CHECK-NEXT: [[PTR:%.*]] = inttoptr i32 [[X:%.*]] to ptr
+; CHECK-NEXT: call void @use_ptr(ptr [[PTR]])
+; CHECK-NEXT: [[P2:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i32 4096
+; CHECK-NEXT: [[R:%.*]] = ptrtoint ptr [[P2]] to i32
+; CHECK-NEXT: ret i32 [[R]]
+;
+ %ptr = inttoptr i32 %x to ptr
+ call void @use_ptr(ptr %ptr)
+ %p2 = getelementptr inbounds i8, ptr %ptr, i32 4096
+ %r = ptrtoint ptr %p2 to i32
+ ret i32 %r
+}
+
+define i32 @ptr_add_in_int_extra_use2(i32 %x) {
+; CHECK-LABEL: @ptr_add_in_int_extra_use2(
+; CHECK-NEXT: [[PTR:%.*]] = inttoptr i32 [[X:%.*]] to ptr
+; CHECK-NEXT: [[P2:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i32 4096
+; CHECK-NEXT: call void @use_ptr(ptr nonnull [[P2]])
+; CHECK-NEXT: [[R:%.*]] = ptrtoint ptr [[P2]] to i32
+; CHECK-NEXT: ret i32 [[R]]
+;
+ %ptr = inttoptr i32 %x to ptr
+ %p2 = getelementptr inbounds i8, ptr %ptr, i32 4096
+ call void @use_ptr(ptr %p2)
+ %r = ptrtoint ptr %p2 to i32
+ ret i32 %r
+}
>From 2ead05c200c649938587ba539eab8c3239b8f740 Mon Sep 17 00:00:00 2001
From: YanWQ-monad <YanWQmonad at gmail.com>
Date: Thu, 9 May 2024 21:19:52 +0800
Subject: [PATCH 2/2] [InstCombine] Fold pointer adding in integer to
arithmetic add
---
llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp | 10 ++++++++++
llvm/test/Transforms/InstCombine/cast_ptr.ll | 8 ++------
2 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
index 11e31877de38c..18ad8706f8843 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
@@ -2073,6 +2073,16 @@ Instruction *InstCombinerImpl::visitPtrToInt(PtrToIntInst &CI) {
return InsertElementInst::Create(Vec, NewCast, Index);
}
+ // (ptrtoint (gep (inttoptr Base), Offset)) -> Base + Offset
+ Value *Base, *Offset;
+ if (match(SrcOp, m_OneUse(m_PtrAdd(m_OneUse(m_IntToPtr(m_Value(Base))),
+ m_Value(Offset)))) &&
+ Base->getType() == Ty && Offset->getType() == Ty) {
+ auto *NewOp = BinaryOperator::CreateAdd(Base, Offset);
+ NewOp->setHasNoUnsignedWrap(true);
+ return NewOp;
+ }
+
return commonCastTransforms(CI);
}
diff --git a/llvm/test/Transforms/InstCombine/cast_ptr.ll b/llvm/test/Transforms/InstCombine/cast_ptr.ll
index 185c02fbdafca..0e191748226df 100644
--- a/llvm/test/Transforms/InstCombine/cast_ptr.ll
+++ b/llvm/test/Transforms/InstCombine/cast_ptr.ll
@@ -247,9 +247,7 @@ define <2 x i32> @insertelt_extra_use2(<2 x i32> %x, ptr %p) {
define i32 @ptr_add_in_int(i32 %x, i32 %y) {
; CHECK-LABEL: @ptr_add_in_int(
-; CHECK-NEXT: [[PTR:%.*]] = inttoptr i32 [[X:%.*]] to ptr
-; CHECK-NEXT: [[P2:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i32 [[Y:%.*]]
-; CHECK-NEXT: [[R:%.*]] = ptrtoint ptr [[P2]] to i32
+; CHECK-NEXT: [[R:%.*]] = add nuw i32 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: ret i32 [[R]]
;
%ptr = inttoptr i32 %x to ptr
@@ -260,9 +258,7 @@ define i32 @ptr_add_in_int(i32 %x, i32 %y) {
define i32 @ptr_add_in_int_const(i32 %x) {
; CHECK-LABEL: @ptr_add_in_int_const(
-; CHECK-NEXT: [[PTR:%.*]] = inttoptr i32 [[X:%.*]] to ptr
-; CHECK-NEXT: [[P2:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i32 4096
-; CHECK-NEXT: [[R:%.*]] = ptrtoint ptr [[P2]] to i32
+; CHECK-NEXT: [[R:%.*]] = add nuw i32 [[X:%.*]], 4096
; CHECK-NEXT: ret i32 [[R]]
;
%ptr = inttoptr i32 %x to ptr
More information about the llvm-commits
mailing list