[llvm] [SCCP] Infer nuw for gep nusw with non-negative offsets (PR #118819)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Thu Dec 5 07:14:32 PST 2024
https://github.com/nikic created https://github.com/llvm/llvm-project/pull/118819
If the GEP is nusw/inbounds and has all-non-negative offsets infer nuw as well.
This doesn't have measurable compile-time impact.
Proof: https://alive2.llvm.org/ce/z/ihztLy
>From 3112c236d6c3366ac6bd61e07cc6afc7aa798f0d Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Thu, 5 Dec 2024 12:10:59 +0100
Subject: [PATCH] [SCCP] Infer nuw for gep nusw with non-negative offsets
If the GEP is nusw/inbounds and has all-non-negative offsets
infer nuw as well.
Proof: https://alive2.llvm.org/ce/z/ihztLy
---
llvm/lib/Transforms/Utils/SCCPSolver.cpp | 10 ++++++++++
.../Transforms/SCCP/conditions-iter-order.ll | 6 +++---
llvm/test/Transforms/SCCP/gep-nuw.ll | 4 ++--
.../SCCP/ipsccp-ssa-copy-nested-conds.ll | 4 ++--
llvm/test/Transforms/SCCP/widening.ll | 16 ++++++++--------
5 files changed, 25 insertions(+), 15 deletions(-)
diff --git a/llvm/lib/Transforms/Utils/SCCPSolver.cpp b/llvm/lib/Transforms/Utils/SCCPSolver.cpp
index 4225e7e80fda6f..81aa7ce1cfe660 100644
--- a/llvm/lib/Transforms/Utils/SCCPSolver.cpp
+++ b/llvm/lib/Transforms/Utils/SCCPSolver.cpp
@@ -147,6 +147,16 @@ static bool refineInstruction(SCCPSolver &Solver,
Changed = true;
}
}
+ } else if (auto *GEP = dyn_cast<GetElementPtrInst>(&Inst)) {
+ if (GEP->hasNoUnsignedWrap() || !GEP->hasNoUnsignedSignedWrap())
+ return false;
+
+ if (all_of(GEP->indices(),
+ [&](Value *V) { return GetRange(V).isAllNonNegative(); })) {
+ GEP->setNoWrapFlags(GEP->getNoWrapFlags() |
+ GEPNoWrapFlags::noUnsignedWrap());
+ Changed = true;
+ }
}
return Changed;
diff --git a/llvm/test/Transforms/SCCP/conditions-iter-order.ll b/llvm/test/Transforms/SCCP/conditions-iter-order.ll
index c7f977b8ab83ae..1e8ba6197ad5f4 100644
--- a/llvm/test/Transforms/SCCP/conditions-iter-order.ll
+++ b/llvm/test/Transforms/SCCP/conditions-iter-order.ll
@@ -13,17 +13,17 @@ define internal ptr @spam(ptr %arg) {
; CHECK-NEXT: [[TMP:%.*]] = call ptr @malloc(i64 10368)
; CHECK-NEXT: [[TMP5:%.*]] = load i32, ptr [[ARG:%.*]], align 8
; CHECK-NEXT: [[TMP6:%.*]] = add i32 [[TMP5]], 1
-; CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds i32, ptr [[ARG]], i32 1
+; CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds nuw i32, ptr [[ARG]], i32 1
; CHECK-NEXT: [[TMP10:%.*]] = icmp ne ptr [[TMP7]], null
; CHECK-NEXT: br i1 [[TMP10]], label [[BB17:%.*]], label [[BB13:%.*]]
; CHECK: bb13:
-; CHECK-NEXT: [[TMP14:%.*]] = getelementptr inbounds i32, ptr [[ARG]], i32 2
+; CHECK-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw i32, ptr [[ARG]], i32 2
; CHECK-NEXT: [[TMP15:%.*]] = load i32, ptr [[TMP14]], align 8
; CHECK-NEXT: [[TMP16:%.*]] = add i32 [[TMP15]], 1
; CHECK-NEXT: br label [[BB30:%.*]]
; CHECK: bb17:
; CHECK-NEXT: [[TMP18:%.*]] = icmp eq i32 [[TMP6]], [[TMP5]]
-; CHECK-NEXT: [[TMP19:%.*]] = getelementptr inbounds i32, ptr [[ARG]], i32 3
+; CHECK-NEXT: [[TMP19:%.*]] = getelementptr inbounds nuw i32, ptr [[ARG]], i32 3
; CHECK-NEXT: [[TMP20:%.*]] = load i32, ptr [[TMP19]], align 8
; CHECK-NEXT: br i1 [[TMP18]], label [[BB30]], label [[BB13]]
; CHECK: bb30:
diff --git a/llvm/test/Transforms/SCCP/gep-nuw.ll b/llvm/test/Transforms/SCCP/gep-nuw.ll
index 298c14adc92a45..4d25642eb85750 100644
--- a/llvm/test/Transforms/SCCP/gep-nuw.ll
+++ b/llvm/test/Transforms/SCCP/gep-nuw.ll
@@ -6,7 +6,7 @@ define ptr @gep_nusw_nneg(ptr %p, i32 %x, i32 %y) {
; CHECK-SAME: ptr [[P:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) {
; CHECK-NEXT: [[X_EXT:%.*]] = zext i32 [[X]] to i64
; CHECK-NEXT: [[Y_EXT:%.*]] = zext i32 [[Y]] to i64
-; CHECK-NEXT: [[GEP:%.*]] = getelementptr nusw [1 x i8], ptr [[P]], i64 [[X_EXT]], i64 [[Y_EXT]]
+; CHECK-NEXT: [[GEP:%.*]] = getelementptr nusw nuw [1 x i8], ptr [[P]], i64 [[X_EXT]], i64 [[Y_EXT]]
; CHECK-NEXT: ret ptr [[GEP]]
;
%x.ext = zext i32 %x to i64
@@ -20,7 +20,7 @@ define ptr @gep_inbounds_nneg(ptr %p, i32 %x, i32 %y) {
; CHECK-SAME: ptr [[P:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) {
; CHECK-NEXT: [[X_EXT:%.*]] = zext i32 [[X]] to i64
; CHECK-NEXT: [[Y_EXT:%.*]] = zext i32 [[Y]] to i64
-; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds [1 x i8], ptr [[P]], i64 [[X_EXT]], i64 [[Y_EXT]]
+; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds nuw [1 x i8], ptr [[P]], i64 [[X_EXT]], i64 [[Y_EXT]]
; CHECK-NEXT: ret ptr [[GEP]]
;
%x.ext = zext i32 %x to i64
diff --git a/llvm/test/Transforms/SCCP/ipsccp-ssa-copy-nested-conds.ll b/llvm/test/Transforms/SCCP/ipsccp-ssa-copy-nested-conds.ll
index 55a7fdf7197e5a..752e5038033106 100644
--- a/llvm/test/Transforms/SCCP/ipsccp-ssa-copy-nested-conds.ll
+++ b/llvm/test/Transforms/SCCP/ipsccp-ssa-copy-nested-conds.ll
@@ -15,11 +15,11 @@ define i32 @check(ptr %node) {
; CHECK: if.end:
; CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[NODE]], align 8
; CHECK-NEXT: [[CALL:%.*]] = call i32 @check(ptr [[TMP0]])
-; CHECK-NEXT: [[RIGHT:%.*]] = getelementptr inbounds [[STRUCT_NODE:%.*]], ptr [[NODE]], i32 0, i32 1
+; CHECK-NEXT: [[RIGHT:%.*]] = getelementptr inbounds nuw [[STRUCT_NODE:%.*]], ptr [[NODE]], i32 0, i32 1
; CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[RIGHT]], align 8
; CHECK-NEXT: [[CALL1:%.*]] = call i32 @check(ptr [[TMP1]])
; CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[RIGHT]], align 8
-; CHECK-NEXT: [[HEIGHT:%.*]] = getelementptr inbounds [[STRUCT_NODE]], ptr [[TMP2]], i32 0, i32 2
+; CHECK-NEXT: [[HEIGHT:%.*]] = getelementptr inbounds nuw [[STRUCT_NODE]], ptr [[TMP2]], i32 0, i32 2
; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[HEIGHT]], align 4
; CHECK-NEXT: [[CMP3:%.*]] = icmp ne i32 [[TMP3]], [[CALL1]]
; CHECK-NEXT: br i1 [[CMP3]], label [[IF_THEN4:%.*]], label [[IF_END5:%.*]]
diff --git a/llvm/test/Transforms/SCCP/widening.ll b/llvm/test/Transforms/SCCP/widening.ll
index 144c3fd54e75b6..8c661bee8f5990 100644
--- a/llvm/test/Transforms/SCCP/widening.ll
+++ b/llvm/test/Transforms/SCCP/widening.ll
@@ -566,7 +566,7 @@ declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias
define linkonce_odr dereferenceable(1) ptr @spam(ptr %arg, i32 %arg1) align 2 {
; SCCP-LABEL: @spam(
; SCCP-NEXT: bb:
-; SCCP-NEXT: [[TMP:%.*]] = getelementptr inbounds [[STRUCT_BAZ_1:%.*]], ptr [[ARG:%.*]], i32 0, i32 3
+; SCCP-NEXT: [[TMP:%.*]] = getelementptr inbounds nuw [[STRUCT_BAZ_1:%.*]], ptr [[ARG:%.*]], i32 0, i32 3
; SCCP-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP]], align 8
; SCCP-NEXT: [[TMP3:%.*]] = sext i32 [[ARG1:%.*]] to i64
; SCCP-NEXT: [[TMP4:%.*]] = getelementptr inbounds i8, ptr [[TMP2]], i64 [[TMP3]]
@@ -574,7 +574,7 @@ define linkonce_odr dereferenceable(1) ptr @spam(ptr %arg, i32 %arg1) align 2 {
;
; IPSCCP-LABEL: @spam(
; IPSCCP-NEXT: bb:
-; IPSCCP-NEXT: [[TMP:%.*]] = getelementptr inbounds [[STRUCT_BAZ_1:%.*]], ptr [[ARG:%.*]], i32 0, i32 3
+; IPSCCP-NEXT: [[TMP:%.*]] = getelementptr inbounds nuw [[STRUCT_BAZ_1:%.*]], ptr [[ARG:%.*]], i32 0, i32 3
; IPSCCP-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP]], align 8
; IPSCCP-NEXT: [[TMP3:%.*]] = sext i32 [[ARG1:%.*]] to i64
; IPSCCP-NEXT: [[TMP4:%.*]] = getelementptr inbounds i8, ptr [[TMP2]], i64 [[TMP3]]
@@ -595,7 +595,7 @@ define ptr @wobble(ptr %arg, i32 %arg1) align 2 {
; SCCP-NEXT: [[TMP2:%.*]] = xor i32 [[TMP]], [[ARG1]]
; SCCP-NEXT: [[TMP3:%.*]] = and i32 [[TMP2]], 65535
; SCCP-NEXT: [[TMP4:%.*]] = mul i32 [[ARG1]], 8
-; SCCP-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT_BLAM_2:%.*]], ptr [[ARG:%.*]], i32 0, i32 1
+; SCCP-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT_BLAM_2:%.*]], ptr [[ARG:%.*]], i32 0, i32 1
; SCCP-NEXT: [[TMP6:%.*]] = load i32, ptr [[TMP5]], align 8
; SCCP-NEXT: [[TMP7:%.*]] = and i32 [[TMP4]], [[TMP6]]
; SCCP-NEXT: br label [[BB8:%.*]]
@@ -609,7 +609,7 @@ define ptr @wobble(ptr %arg, i32 %arg1) align 2 {
; SCCP-NEXT: [[TMP15:%.*]] = add i32 [[TMP7]], [[TMP11]]
; SCCP-NEXT: [[TMP16:%.*]] = mul i32 [[TMP15]], 4
; SCCP-NEXT: [[TMP17]] = call dereferenceable(1) ptr @spam(ptr [[ARG]], i32 [[TMP16]])
-; SCCP-NEXT: [[TMP19:%.*]] = getelementptr inbounds i8, ptr [[TMP17]], i64 2
+; SCCP-NEXT: [[TMP19:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP17]], i64 2
; SCCP-NEXT: [[TMP20:%.*]] = load i8, ptr [[TMP19]], align 1
; SCCP-NEXT: [[TMP21:%.*]] = zext i8 [[TMP20]] to i32
; SCCP-NEXT: [[TMP22:%.*]] = icmp eq i32 [[TMP21]], 0
@@ -632,7 +632,7 @@ define ptr @wobble(ptr %arg, i32 %arg1) align 2 {
; SCCP-NEXT: [[TMP34:%.*]] = icmp eq i32 [[TMP11]], 0
; SCCP-NEXT: br i1 [[TMP34]], label [[BB35:%.*]], label [[BB37:%.*]]
; SCCP: bb35:
-; SCCP-NEXT: [[TMP36:%.*]] = getelementptr inbounds i8, ptr [[TMP32]], i64 1
+; SCCP-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP32]], i64 1
; SCCP-NEXT: br label [[BB66:%.*]]
; SCCP: bb37:
; SCCP-NEXT: [[C_2:%.*]] = icmp eq i32 [[TMP11]], 8
@@ -677,7 +677,7 @@ define ptr @wobble(ptr %arg, i32 %arg1) align 2 {
; IPSCCP-NEXT: [[TMP2:%.*]] = xor i32 [[TMP]], [[ARG1]]
; IPSCCP-NEXT: [[TMP3:%.*]] = and i32 [[TMP2]], 65535
; IPSCCP-NEXT: [[TMP4:%.*]] = mul i32 [[ARG1]], 8
-; IPSCCP-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT_BLAM_2:%.*]], ptr [[ARG:%.*]], i32 0, i32 1
+; IPSCCP-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT_BLAM_2:%.*]], ptr [[ARG:%.*]], i32 0, i32 1
; IPSCCP-NEXT: [[TMP6:%.*]] = load i32, ptr [[TMP5]], align 8
; IPSCCP-NEXT: [[TMP7:%.*]] = and i32 [[TMP4]], [[TMP6]]
; IPSCCP-NEXT: br label [[BB8:%.*]]
@@ -691,7 +691,7 @@ define ptr @wobble(ptr %arg, i32 %arg1) align 2 {
; IPSCCP-NEXT: [[TMP15:%.*]] = add i32 [[TMP7]], [[TMP11]]
; IPSCCP-NEXT: [[TMP16:%.*]] = mul i32 [[TMP15]], 4
; IPSCCP-NEXT: [[TMP17]] = call dereferenceable(1) ptr @spam(ptr [[ARG]], i32 [[TMP16]])
-; IPSCCP-NEXT: [[TMP19:%.*]] = getelementptr inbounds i8, ptr [[TMP17]], i64 2
+; IPSCCP-NEXT: [[TMP19:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP17]], i64 2
; IPSCCP-NEXT: [[TMP20:%.*]] = load i8, ptr [[TMP19]], align 1
; IPSCCP-NEXT: [[TMP21:%.*]] = zext i8 [[TMP20]] to i32
; IPSCCP-NEXT: [[TMP22:%.*]] = icmp eq i32 [[TMP21]], 0
@@ -714,7 +714,7 @@ define ptr @wobble(ptr %arg, i32 %arg1) align 2 {
; IPSCCP-NEXT: [[TMP34:%.*]] = icmp eq i32 [[TMP11]], 0
; IPSCCP-NEXT: br i1 [[TMP34]], label [[BB35:%.*]], label [[BB37:%.*]]
; IPSCCP: bb35:
-; IPSCCP-NEXT: [[TMP36:%.*]] = getelementptr inbounds i8, ptr [[TMP32]], i64 1
+; IPSCCP-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP32]], i64 1
; IPSCCP-NEXT: br label [[BB66:%.*]]
; IPSCCP: bb37:
; IPSCCP-NEXT: [[C_2:%.*]] = icmp eq i32 [[TMP11]], 8
More information about the llvm-commits
mailing list