Skip to content

Commit f223184

Browse files
committed
[InstCombine] Fold icmp of gep chain with base
Fold icmp between a chain of geps and its based pointer. Previously only a single gep was supported. This will be extended to handle the case of two gep chains with a common base in a followup.
1 parent b1e4bf8 commit f223184

File tree

4 files changed

+21
-25
lines changed

4 files changed

+21
-25
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -708,10 +708,12 @@ Instruction *InstCombinerImpl::foldGEPICmp(GEPOperator *GEPLHS, Value *RHS,
708708
return I;
709709
};
710710

711-
Value *PtrBase = GEPLHS->getOperand(0);
712-
if (PtrBase == RHS && CanFold(GEPLHS->getNoWrapFlags())) {
711+
CommonPointerBase Base = CommonPointerBase::compute(GEPLHS, RHS);
712+
if (Base.Ptr == RHS && CanFold(Base.LHSNW)) {
713713
// ((gep Ptr, OFFSET) cmp Ptr) ---> (OFFSET cmp 0).
714-
Value *Offset = EmitGEPOffset(GEPLHS);
714+
Type *IdxTy = DL.getIndexType(GEPLHS->getType());
715+
Value *Offset =
716+
EmitGEPOffsets(Base.LHSGEPs, Base.LHSNW, IdxTy, /*RewriteGEPs=*/false);
715717
return NewICmp(GEPLHS->getNoWrapFlags(), Offset,
716718
Constant::getNullValue(Offset->getType()));
717719
}
@@ -750,6 +752,7 @@ Instruction *InstCombinerImpl::foldGEPICmp(GEPOperator *GEPLHS, Value *RHS,
750752

751753
// If the base pointers are different, but the indices are the same, just
752754
// compare the base pointer.
755+
Value *PtrBase = GEPLHS->getOperand(0);
753756
if (PtrBase != GEPRHS->getOperand(0)) {
754757
bool IndicesTheSame =
755758
GEPLHS->getNumOperands() == GEPRHS->getNumOperands() &&

llvm/test/Transforms/InstCombine/getelementptr.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -694,7 +694,7 @@ define i32 @test28() nounwind {
694694
; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[T12_REC]] to i64
695695
; CHECK-NEXT: [[T12:%.*]] = getelementptr inbounds [[STRUCT_X:%.*]], ptr [[T45]], i64 [[TMP0]]
696696
; CHECK-NEXT: [[T16:%.*]] = call i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str1, ptr nonnull [[T12]]) #[[ATTR0]]
697-
; CHECK-NEXT: [[T84:%.*]] = icmp eq ptr [[T12]], [[ORIENTATIONS]]
697+
; CHECK-NEXT: [[T84:%.*]] = icmp eq i32 [[INDVAR]], 0
698698
; CHECK-NEXT: [[INDVAR_NEXT]] = add i32 [[INDVAR]], 1
699699
; CHECK-NEXT: br i1 [[T84]], label [[BB17:%.*]], label [[BB10]]
700700
; CHECK: bb17:

llvm/test/Transforms/InstCombine/icmp-gep.ll

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -760,9 +760,9 @@ define i1 @gep_diff_base_same_indices_nuw_nusw(ptr %x, ptr %y, i64 %z) {
760760

761761
define i1 @gep_multiple_eq(ptr %base, i64 %idx, i64 %idx2) {
762762
; CHECK-LABEL: @gep_multiple_eq(
763-
; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i32, ptr [[BASE:%.*]], i64 [[IDX:%.*]]
764-
; CHECK-NEXT: [[GEP2:%.*]] = getelementptr i32, ptr [[GEP1]], i64 [[IDX2:%.*]]
765-
; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[GEP2]], [[BASE]]
763+
; CHECK-NEXT: [[GEP1_IDX1:%.*]] = add i64 [[IDX:%.*]], [[IDX2:%.*]]
764+
; CHECK-NEXT: [[DOTMASK:%.*]] = and i64 [[GEP1_IDX1]], 4611686018427387903
765+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[DOTMASK]], 0
766766
; CHECK-NEXT: ret i1 [[CMP]]
767767
;
768768
%gep1 = getelementptr i32, ptr %base, i64 %idx
@@ -773,9 +773,9 @@ define i1 @gep_multiple_eq(ptr %base, i64 %idx, i64 %idx2) {
773773

774774
define i1 @gep_multiple_eq_commuted(ptr %base, i64 %idx, i64 %idx2) {
775775
; CHECK-LABEL: @gep_multiple_eq_commuted(
776-
; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i32, ptr [[BASE:%.*]], i64 [[IDX:%.*]]
777-
; CHECK-NEXT: [[GEP2:%.*]] = getelementptr i32, ptr [[GEP1]], i64 [[IDX2:%.*]]
778-
; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[BASE]], [[GEP2]]
776+
; CHECK-NEXT: [[GEP1_IDX1:%.*]] = add i64 [[IDX:%.*]], [[IDX2:%.*]]
777+
; CHECK-NEXT: [[DOTMASK:%.*]] = and i64 [[GEP1_IDX1]], 4611686018427387903
778+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[DOTMASK]], 0
779779
; CHECK-NEXT: ret i1 [[CMP]]
780780
;
781781
%gep1 = getelementptr i32, ptr %base, i64 %idx
@@ -786,9 +786,8 @@ define i1 @gep_multiple_eq_commuted(ptr %base, i64 %idx, i64 %idx2) {
786786

787787
define i1 @gep_mugtiple_ugt_nuw(ptr %base, i64 %idx, i64 %idx2) {
788788
; CHECK-LABEL: @gep_mugtiple_ugt_nuw(
789-
; CHECK-NEXT: [[GEP1:%.*]] = getelementptr nuw i32, ptr [[BASE:%.*]], i64 [[IDX:%.*]]
790-
; CHECK-NEXT: [[GEP2:%.*]] = getelementptr nuw i32, ptr [[GEP1]], i64 [[IDX2:%.*]]
791-
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt ptr [[GEP2]], [[BASE]]
789+
; CHECK-NEXT: [[GEP1_IDX1:%.*]] = sub i64 0, [[IDX2:%.*]]
790+
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i64 [[IDX:%.*]], [[GEP1_IDX1]]
792791
; CHECK-NEXT: ret i1 [[CMP]]
793792
;
794793
%gep1 = getelementptr nuw i32, ptr %base, i64 %idx
@@ -812,9 +811,9 @@ define i1 @gep_mugtiple_ugt_not_all_nuw(ptr %base, i64 %idx, i64 %idx2) {
812811

813812
define i1 @gep_mugtiple_ugt_inbounds_nusw(ptr %base, i64 %idx, i64 %idx2) {
814813
; CHECK-LABEL: @gep_mugtiple_ugt_inbounds_nusw(
815-
; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds i32, ptr [[BASE:%.*]], i64 [[IDX:%.*]]
816-
; CHECK-NEXT: [[GEP2:%.*]] = getelementptr nusw i32, ptr [[GEP1]], i64 [[IDX2:%.*]]
817-
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt ptr [[GEP2]], [[BASE]]
814+
; CHECK-NEXT: [[GEP1_IDX1:%.*]] = add i64 [[IDX:%.*]], [[IDX2:%.*]]
815+
; CHECK-NEXT: [[TMP1:%.*]] = shl i64 [[GEP1_IDX1]], 2
816+
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[TMP1]], 0
818817
; CHECK-NEXT: ret i1 [[CMP]]
819818
;
820819
%gep1 = getelementptr inbounds i32, ptr %base, i64 %idx

llvm/test/Transforms/InstCombine/pr39908.ll

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,7 @@ target datalayout = "p:32:32"
77

88
define i1 @test(ptr %p, i32 %n) {
99
; CHECK-LABEL: @test(
10-
; CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [0 x %S], ptr [[P:%.*]], i32 0, i32 [[N:%.*]], i32 0, i32 0
11-
; CHECK-NEXT: [[LAST:%.*]] = getelementptr inbounds i8, ptr [[END]], i32 -8
12-
; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[LAST]], [[P]]
10+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[N:%.*]], 1
1311
; CHECK-NEXT: ret i1 [[CMP]]
1412
;
1513
%end = getelementptr inbounds [0 x %S], ptr %p, i32 0, i32 %n, i32 0, i32 0
@@ -22,9 +20,7 @@ define i1 @test(ptr %p, i32 %n) {
2220
define i1 @test64(ptr %p, i64 %n) {
2321
; CHECK-LABEL: @test64(
2422
; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[N:%.*]] to i32
25-
; CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [0 x %S], ptr [[P:%.*]], i32 0, i32 [[TMP1]], i32 0, i32 0
26-
; CHECK-NEXT: [[LAST:%.*]] = getelementptr inbounds i8, ptr [[END]], i32 -8
27-
; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[LAST]], [[P]]
23+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 1
2824
; CHECK-NEXT: ret i1 [[CMP]]
2925
;
3026
%end = getelementptr inbounds [0 x %S], ptr %p, i64 0, i64 %n, i32 0, i64 0
@@ -37,9 +33,7 @@ define i1 @test64(ptr %p, i64 %n) {
3733
define i1 @test64_overflow(ptr %p, i64 %n) {
3834
; CHECK-LABEL: @test64_overflow(
3935
; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[N:%.*]] to i32
40-
; CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [0 x %S], ptr [[P:%.*]], i32 0, i32 [[TMP1]], i32 0, i32 0
41-
; CHECK-NEXT: [[LAST:%.*]] = getelementptr inbounds i8, ptr [[END]], i32 -8
42-
; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[LAST]], [[P]]
36+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 1
4337
; CHECK-NEXT: ret i1 [[CMP]]
4438
;
4539
%end = getelementptr inbounds [0 x %S], ptr %p, i64 0, i64 %n, i32 0, i64 8589934592

0 commit comments

Comments
 (0)