Skip to content

Commit fe56f19

Browse files
committed
[Local] Use nusw and nuw flags in emitGEPOffset()
1 parent 59cb55d commit fe56f19

File tree

2 files changed

+39
-6
lines changed

2 files changed

+39
-6
lines changed

llvm/lib/Analysis/Local.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,13 @@ Value *llvm::emitGEPOffset(IRBuilderBase *Builder, const DataLayout &DL,
2525
Type *IntIdxTy = DL.getIndexType(GEP->getType());
2626
Value *Result = nullptr;
2727

28-
// If the GEP is inbounds, we know that none of the addressing operations will
29-
// overflow in a signed sense.
30-
bool isInBounds = GEPOp->isInBounds() && !NoAssumptions;
28+
// nusw implies nsw for the offset arithmetic.
29+
bool NSW = GEPOp->hasNoUnsignedSignedWrap() && !NoAssumptions;
30+
bool NUW = GEPOp->hasNoUnsignedWrap() && !NoAssumptions;
3131
auto AddOffset = [&](Value *Offset) {
3232
if (Result)
3333
Result = Builder->CreateAdd(Result, Offset, GEP->getName() + ".offs",
34-
false /*NUW*/, isInBounds /*NSW*/);
34+
NUW, NSW);
3535
else
3636
Result = Offset;
3737
};
@@ -71,8 +71,7 @@ Value *llvm::emitGEPOffset(IRBuilderBase *Builder, const DataLayout &DL,
7171
Scale = Builder->CreateVectorSplat(
7272
cast<VectorType>(IntIdxTy)->getElementCount(), Scale);
7373
// We'll let instcombine(mul) convert this to a shl if possible.
74-
Op = Builder->CreateMul(Op, Scale, GEP->getName() + ".idx", false /*NUW*/,
75-
isInBounds /*NSW*/);
74+
Op = Builder->CreateMul(Op, Scale, GEP->getName() + ".idx", NUW, NSW);
7675
}
7776
AddOffset(Op);
7877
}

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

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,3 +546,37 @@ define i1 @test_scalable_ij(ptr %foo, i64 %i, i64 %j) {
546546
%cmp = icmp ult ptr %gep1, %gep2
547547
ret i1 %cmp
548548
}
549+
550+
define i1 @gep_nuw(ptr %p, i64 %a, i64 %b, i64 %c, i64 %d) {
551+
; CHECK-LABEL: @gep_nuw(
552+
; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nuw i64 [[A:%.*]], 2
553+
; CHECK-NEXT: [[GEP1_IDX1:%.*]] = shl nuw i64 [[B:%.*]], 1
554+
; CHECK-NEXT: [[GEP1_OFFS:%.*]] = add nuw i64 [[GEP1_IDX]], [[GEP1_IDX1]]
555+
; CHECK-NEXT: [[GEP2_IDX:%.*]] = shl nuw i64 [[C:%.*]], 3
556+
; CHECK-NEXT: [[GEP2_IDX2:%.*]] = shl nuw i64 [[D:%.*]], 2
557+
; CHECK-NEXT: [[GEP2_OFFS:%.*]] = add nuw i64 [[GEP2_IDX]], [[GEP2_IDX2]]
558+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[GEP1_OFFS]], [[GEP2_OFFS]]
559+
; CHECK-NEXT: ret i1 [[CMP]]
560+
;
561+
%gep1 = getelementptr nuw [2 x i16], ptr %p, i64 %a, i64 %b
562+
%gep2 = getelementptr nuw [2 x i32], ptr %p, i64 %c, i64 %d
563+
%cmp = icmp eq ptr %gep1, %gep2
564+
ret i1 %cmp
565+
}
566+
567+
define i1 @gep_nusw(ptr %p, i64 %a, i64 %b, i64 %c, i64 %d) {
568+
; CHECK-LABEL: @gep_nusw(
569+
; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nsw i64 [[A:%.*]], 2
570+
; CHECK-NEXT: [[GEP1_IDX1:%.*]] = shl nsw i64 [[B:%.*]], 1
571+
; CHECK-NEXT: [[GEP1_OFFS:%.*]] = add nsw i64 [[GEP1_IDX]], [[GEP1_IDX1]]
572+
; CHECK-NEXT: [[GEP2_IDX:%.*]] = shl nsw i64 [[C:%.*]], 3
573+
; CHECK-NEXT: [[GEP2_IDX2:%.*]] = shl nsw i64 [[D:%.*]], 2
574+
; CHECK-NEXT: [[GEP2_OFFS:%.*]] = add nsw i64 [[GEP2_IDX]], [[GEP2_IDX2]]
575+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[GEP1_OFFS]], [[GEP2_OFFS]]
576+
; CHECK-NEXT: ret i1 [[CMP]]
577+
;
578+
%gep1 = getelementptr nusw [2 x i16], ptr %p, i64 %a, i64 %b
579+
%gep2 = getelementptr nusw [2 x i32], ptr %p, i64 %c, i64 %d
580+
%cmp = icmp eq ptr %gep1, %gep2
581+
ret i1 %cmp
582+
}

0 commit comments

Comments
 (0)