Skip to content

Commit 3112c23

Browse files
committed
[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
1 parent 2bd3174 commit 3112c23

File tree

5 files changed

+25
-15
lines changed

5 files changed

+25
-15
lines changed

llvm/lib/Transforms/Utils/SCCPSolver.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,16 @@ static bool refineInstruction(SCCPSolver &Solver,
147147
Changed = true;
148148
}
149149
}
150+
} else if (auto *GEP = dyn_cast<GetElementPtrInst>(&Inst)) {
151+
if (GEP->hasNoUnsignedWrap() || !GEP->hasNoUnsignedSignedWrap())
152+
return false;
153+
154+
if (all_of(GEP->indices(),
155+
[&](Value *V) { return GetRange(V).isAllNonNegative(); })) {
156+
GEP->setNoWrapFlags(GEP->getNoWrapFlags() |
157+
GEPNoWrapFlags::noUnsignedWrap());
158+
Changed = true;
159+
}
150160
}
151161

152162
return Changed;

llvm/test/Transforms/SCCP/conditions-iter-order.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,17 @@ define internal ptr @spam(ptr %arg) {
1313
; CHECK-NEXT: [[TMP:%.*]] = call ptr @malloc(i64 10368)
1414
; CHECK-NEXT: [[TMP5:%.*]] = load i32, ptr [[ARG:%.*]], align 8
1515
; CHECK-NEXT: [[TMP6:%.*]] = add i32 [[TMP5]], 1
16-
; CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds i32, ptr [[ARG]], i32 1
16+
; CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds nuw i32, ptr [[ARG]], i32 1
1717
; CHECK-NEXT: [[TMP10:%.*]] = icmp ne ptr [[TMP7]], null
1818
; CHECK-NEXT: br i1 [[TMP10]], label [[BB17:%.*]], label [[BB13:%.*]]
1919
; CHECK: bb13:
20-
; CHECK-NEXT: [[TMP14:%.*]] = getelementptr inbounds i32, ptr [[ARG]], i32 2
20+
; CHECK-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw i32, ptr [[ARG]], i32 2
2121
; CHECK-NEXT: [[TMP15:%.*]] = load i32, ptr [[TMP14]], align 8
2222
; CHECK-NEXT: [[TMP16:%.*]] = add i32 [[TMP15]], 1
2323
; CHECK-NEXT: br label [[BB30:%.*]]
2424
; CHECK: bb17:
2525
; CHECK-NEXT: [[TMP18:%.*]] = icmp eq i32 [[TMP6]], [[TMP5]]
26-
; CHECK-NEXT: [[TMP19:%.*]] = getelementptr inbounds i32, ptr [[ARG]], i32 3
26+
; CHECK-NEXT: [[TMP19:%.*]] = getelementptr inbounds nuw i32, ptr [[ARG]], i32 3
2727
; CHECK-NEXT: [[TMP20:%.*]] = load i32, ptr [[TMP19]], align 8
2828
; CHECK-NEXT: br i1 [[TMP18]], label [[BB30]], label [[BB13]]
2929
; CHECK: bb30:

llvm/test/Transforms/SCCP/gep-nuw.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ define ptr @gep_nusw_nneg(ptr %p, i32 %x, i32 %y) {
66
; CHECK-SAME: ptr [[P:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) {
77
; CHECK-NEXT: [[X_EXT:%.*]] = zext i32 [[X]] to i64
88
; CHECK-NEXT: [[Y_EXT:%.*]] = zext i32 [[Y]] to i64
9-
; CHECK-NEXT: [[GEP:%.*]] = getelementptr nusw [1 x i8], ptr [[P]], i64 [[X_EXT]], i64 [[Y_EXT]]
9+
; CHECK-NEXT: [[GEP:%.*]] = getelementptr nusw nuw [1 x i8], ptr [[P]], i64 [[X_EXT]], i64 [[Y_EXT]]
1010
; CHECK-NEXT: ret ptr [[GEP]]
1111
;
1212
%x.ext = zext i32 %x to i64
@@ -20,7 +20,7 @@ define ptr @gep_inbounds_nneg(ptr %p, i32 %x, i32 %y) {
2020
; CHECK-SAME: ptr [[P:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) {
2121
; CHECK-NEXT: [[X_EXT:%.*]] = zext i32 [[X]] to i64
2222
; CHECK-NEXT: [[Y_EXT:%.*]] = zext i32 [[Y]] to i64
23-
; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds [1 x i8], ptr [[P]], i64 [[X_EXT]], i64 [[Y_EXT]]
23+
; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds nuw [1 x i8], ptr [[P]], i64 [[X_EXT]], i64 [[Y_EXT]]
2424
; CHECK-NEXT: ret ptr [[GEP]]
2525
;
2626
%x.ext = zext i32 %x to i64

llvm/test/Transforms/SCCP/ipsccp-ssa-copy-nested-conds.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@ define i32 @check(ptr %node) {
1515
; CHECK: if.end:
1616
; CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[NODE]], align 8
1717
; CHECK-NEXT: [[CALL:%.*]] = call i32 @check(ptr [[TMP0]])
18-
; CHECK-NEXT: [[RIGHT:%.*]] = getelementptr inbounds [[STRUCT_NODE:%.*]], ptr [[NODE]], i32 0, i32 1
18+
; CHECK-NEXT: [[RIGHT:%.*]] = getelementptr inbounds nuw [[STRUCT_NODE:%.*]], ptr [[NODE]], i32 0, i32 1
1919
; CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[RIGHT]], align 8
2020
; CHECK-NEXT: [[CALL1:%.*]] = call i32 @check(ptr [[TMP1]])
2121
; CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[RIGHT]], align 8
22-
; CHECK-NEXT: [[HEIGHT:%.*]] = getelementptr inbounds [[STRUCT_NODE]], ptr [[TMP2]], i32 0, i32 2
22+
; CHECK-NEXT: [[HEIGHT:%.*]] = getelementptr inbounds nuw [[STRUCT_NODE]], ptr [[TMP2]], i32 0, i32 2
2323
; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[HEIGHT]], align 4
2424
; CHECK-NEXT: [[CMP3:%.*]] = icmp ne i32 [[TMP3]], [[CALL1]]
2525
; CHECK-NEXT: br i1 [[CMP3]], label [[IF_THEN4:%.*]], label [[IF_END5:%.*]]

llvm/test/Transforms/SCCP/widening.ll

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -566,15 +566,15 @@ declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias
566566
define linkonce_odr dereferenceable(1) ptr @spam(ptr %arg, i32 %arg1) align 2 {
567567
; SCCP-LABEL: @spam(
568568
; SCCP-NEXT: bb:
569-
; SCCP-NEXT: [[TMP:%.*]] = getelementptr inbounds [[STRUCT_BAZ_1:%.*]], ptr [[ARG:%.*]], i32 0, i32 3
569+
; SCCP-NEXT: [[TMP:%.*]] = getelementptr inbounds nuw [[STRUCT_BAZ_1:%.*]], ptr [[ARG:%.*]], i32 0, i32 3
570570
; SCCP-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP]], align 8
571571
; SCCP-NEXT: [[TMP3:%.*]] = sext i32 [[ARG1:%.*]] to i64
572572
; SCCP-NEXT: [[TMP4:%.*]] = getelementptr inbounds i8, ptr [[TMP2]], i64 [[TMP3]]
573573
; SCCP-NEXT: ret ptr [[TMP4]]
574574
;
575575
; IPSCCP-LABEL: @spam(
576576
; IPSCCP-NEXT: bb:
577-
; IPSCCP-NEXT: [[TMP:%.*]] = getelementptr inbounds [[STRUCT_BAZ_1:%.*]], ptr [[ARG:%.*]], i32 0, i32 3
577+
; IPSCCP-NEXT: [[TMP:%.*]] = getelementptr inbounds nuw [[STRUCT_BAZ_1:%.*]], ptr [[ARG:%.*]], i32 0, i32 3
578578
; IPSCCP-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP]], align 8
579579
; IPSCCP-NEXT: [[TMP3:%.*]] = sext i32 [[ARG1:%.*]] to i64
580580
; IPSCCP-NEXT: [[TMP4:%.*]] = getelementptr inbounds i8, ptr [[TMP2]], i64 [[TMP3]]
@@ -595,7 +595,7 @@ define ptr @wobble(ptr %arg, i32 %arg1) align 2 {
595595
; SCCP-NEXT: [[TMP2:%.*]] = xor i32 [[TMP]], [[ARG1]]
596596
; SCCP-NEXT: [[TMP3:%.*]] = and i32 [[TMP2]], 65535
597597
; SCCP-NEXT: [[TMP4:%.*]] = mul i32 [[ARG1]], 8
598-
; SCCP-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT_BLAM_2:%.*]], ptr [[ARG:%.*]], i32 0, i32 1
598+
; SCCP-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT_BLAM_2:%.*]], ptr [[ARG:%.*]], i32 0, i32 1
599599
; SCCP-NEXT: [[TMP6:%.*]] = load i32, ptr [[TMP5]], align 8
600600
; SCCP-NEXT: [[TMP7:%.*]] = and i32 [[TMP4]], [[TMP6]]
601601
; SCCP-NEXT: br label [[BB8:%.*]]
@@ -609,7 +609,7 @@ define ptr @wobble(ptr %arg, i32 %arg1) align 2 {
609609
; SCCP-NEXT: [[TMP15:%.*]] = add i32 [[TMP7]], [[TMP11]]
610610
; SCCP-NEXT: [[TMP16:%.*]] = mul i32 [[TMP15]], 4
611611
; SCCP-NEXT: [[TMP17]] = call dereferenceable(1) ptr @spam(ptr [[ARG]], i32 [[TMP16]])
612-
; SCCP-NEXT: [[TMP19:%.*]] = getelementptr inbounds i8, ptr [[TMP17]], i64 2
612+
; SCCP-NEXT: [[TMP19:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP17]], i64 2
613613
; SCCP-NEXT: [[TMP20:%.*]] = load i8, ptr [[TMP19]], align 1
614614
; SCCP-NEXT: [[TMP21:%.*]] = zext i8 [[TMP20]] to i32
615615
; SCCP-NEXT: [[TMP22:%.*]] = icmp eq i32 [[TMP21]], 0
@@ -632,7 +632,7 @@ define ptr @wobble(ptr %arg, i32 %arg1) align 2 {
632632
; SCCP-NEXT: [[TMP34:%.*]] = icmp eq i32 [[TMP11]], 0
633633
; SCCP-NEXT: br i1 [[TMP34]], label [[BB35:%.*]], label [[BB37:%.*]]
634634
; SCCP: bb35:
635-
; SCCP-NEXT: [[TMP36:%.*]] = getelementptr inbounds i8, ptr [[TMP32]], i64 1
635+
; SCCP-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP32]], i64 1
636636
; SCCP-NEXT: br label [[BB66:%.*]]
637637
; SCCP: bb37:
638638
; SCCP-NEXT: [[C_2:%.*]] = icmp eq i32 [[TMP11]], 8
@@ -677,7 +677,7 @@ define ptr @wobble(ptr %arg, i32 %arg1) align 2 {
677677
; IPSCCP-NEXT: [[TMP2:%.*]] = xor i32 [[TMP]], [[ARG1]]
678678
; IPSCCP-NEXT: [[TMP3:%.*]] = and i32 [[TMP2]], 65535
679679
; IPSCCP-NEXT: [[TMP4:%.*]] = mul i32 [[ARG1]], 8
680-
; IPSCCP-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT_BLAM_2:%.*]], ptr [[ARG:%.*]], i32 0, i32 1
680+
; IPSCCP-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT_BLAM_2:%.*]], ptr [[ARG:%.*]], i32 0, i32 1
681681
; IPSCCP-NEXT: [[TMP6:%.*]] = load i32, ptr [[TMP5]], align 8
682682
; IPSCCP-NEXT: [[TMP7:%.*]] = and i32 [[TMP4]], [[TMP6]]
683683
; IPSCCP-NEXT: br label [[BB8:%.*]]
@@ -691,7 +691,7 @@ define ptr @wobble(ptr %arg, i32 %arg1) align 2 {
691691
; IPSCCP-NEXT: [[TMP15:%.*]] = add i32 [[TMP7]], [[TMP11]]
692692
; IPSCCP-NEXT: [[TMP16:%.*]] = mul i32 [[TMP15]], 4
693693
; IPSCCP-NEXT: [[TMP17]] = call dereferenceable(1) ptr @spam(ptr [[ARG]], i32 [[TMP16]])
694-
; IPSCCP-NEXT: [[TMP19:%.*]] = getelementptr inbounds i8, ptr [[TMP17]], i64 2
694+
; IPSCCP-NEXT: [[TMP19:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP17]], i64 2
695695
; IPSCCP-NEXT: [[TMP20:%.*]] = load i8, ptr [[TMP19]], align 1
696696
; IPSCCP-NEXT: [[TMP21:%.*]] = zext i8 [[TMP20]] to i32
697697
; IPSCCP-NEXT: [[TMP22:%.*]] = icmp eq i32 [[TMP21]], 0
@@ -714,7 +714,7 @@ define ptr @wobble(ptr %arg, i32 %arg1) align 2 {
714714
; IPSCCP-NEXT: [[TMP34:%.*]] = icmp eq i32 [[TMP11]], 0
715715
; IPSCCP-NEXT: br i1 [[TMP34]], label [[BB35:%.*]], label [[BB37:%.*]]
716716
; IPSCCP: bb35:
717-
; IPSCCP-NEXT: [[TMP36:%.*]] = getelementptr inbounds i8, ptr [[TMP32]], i64 1
717+
; IPSCCP-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP32]], i64 1
718718
; IPSCCP-NEXT: br label [[BB66:%.*]]
719719
; IPSCCP: bb37:
720720
; IPSCCP-NEXT: [[C_2:%.*]] = icmp eq i32 [[TMP11]], 8

0 commit comments

Comments
 (0)