Skip to content

Commit 6fc8ec7

Browse files
authored
[InstCombine] Restore splat gep support in OptimizePointerDifference() (#143906)
When looking for the common base pointer, support the case where the type changes because the GEP goes from pointer to vector of pointers. This was supported prior to #142958.
1 parent e2c27fd commit 6fc8ec7

File tree

2 files changed

+34
-3
lines changed

2 files changed

+34
-3
lines changed

llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2088,8 +2088,6 @@ CommonPointerBase CommonPointerBase::compute(Value *LHS, Value *RHS) {
20882088
// Find common base and collect RHS GEPs.
20892089
while (true) {
20902090
if (Ptrs.contains(RHS)) {
2091-
if (LHS->getType() != RHS->getType())
2092-
return Base;
20932091
Base.Ptr = RHS;
20942092
break;
20952093
}
@@ -2132,12 +2130,15 @@ Value *InstCombinerImpl::OptimizePointerDifference(Value *LHS, Value *RHS,
21322130
// TODO: We should probably do this even if there is only one GEP.
21332131
bool RewriteGEPs = !Base.LHSGEPs.empty() && !Base.RHSGEPs.empty();
21342132

2135-
Type *IdxTy = DL.getIndexType(Base.Ptr->getType());
2133+
Type *IdxTy = DL.getIndexType(LHS->getType());
21362134
auto EmitOffsetFromBase = [&](ArrayRef<GEPOperator *> GEPs,
21372135
GEPNoWrapFlags NW) -> Value * {
21382136
Value *Sum = nullptr;
21392137
for (GEPOperator *GEP : reverse(GEPs)) {
21402138
Value *Offset = EmitGEPOffset(GEP, RewriteGEPs);
2139+
if (Offset->getType() != IdxTy)
2140+
Offset = Builder.CreateVectorSplat(
2141+
cast<VectorType>(IdxTy)->getElementCount(), Offset);
21412142
if (Sum)
21422143
Sum = Builder.CreateAdd(Sum, Offset, "", NW.hasNoUnsignedWrap(),
21432144
NW.isInBounds());

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

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -995,3 +995,33 @@ define i64 @multiple_geps_inbounds_nuw(ptr %base, i64 %idx, i64 %idx2) {
995995
%d = sub i64 %i2, %i1
996996
ret i64 %d
997997
}
998+
999+
define <2 x i64> @splat_geps(ptr %base, <2 x i64> %idx1, <2 x i64> %idx2) {
1000+
; CHECK-LABEL: @splat_geps(
1001+
; CHECK-NEXT: [[D:%.*]] = sub nsw <2 x i64> [[IDX2:%.*]], [[IDX1:%.*]]
1002+
; CHECK-NEXT: ret <2 x i64> [[D]]
1003+
;
1004+
%gep1 = getelementptr inbounds i8, ptr %base, <2 x i64> %idx1
1005+
%gep2 = getelementptr inbounds i8, ptr %base, <2 x i64> %idx2
1006+
%gep1.int = ptrtoint <2 x ptr> %gep1 to <2 x i64>
1007+
%gep2.int = ptrtoint <2 x ptr> %gep2 to <2 x i64>
1008+
%d = sub <2 x i64> %gep2.int, %gep1.int
1009+
ret <2 x i64> %d
1010+
}
1011+
1012+
define <2 x i64> @splat_geps_multiple(ptr %base, i64 %idx0, <2 x i64> %idx1, <2 x i64> %idx2) {
1013+
; CHECK-LABEL: @splat_geps_multiple(
1014+
; CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <2 x i64> poison, i64 [[IDX0:%.*]], i64 0
1015+
; CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector <2 x i64> [[DOTSPLATINSERT]], <2 x i64> poison, <2 x i32> zeroinitializer
1016+
; CHECK-NEXT: [[TMP1:%.*]] = add nsw <2 x i64> [[DOTSPLAT]], [[IDX1:%.*]]
1017+
; CHECK-NEXT: [[D:%.*]] = sub nsw <2 x i64> [[IDX2:%.*]], [[TMP1]]
1018+
; CHECK-NEXT: ret <2 x i64> [[D]]
1019+
;
1020+
%gep0 = getelementptr inbounds i8, ptr %base, i64 %idx0
1021+
%gep1 = getelementptr inbounds i8, ptr %gep0, <2 x i64> %idx1
1022+
%gep2 = getelementptr inbounds i8, ptr %base, <2 x i64> %idx2
1023+
%gep1.int = ptrtoint <2 x ptr> %gep1 to <2 x i64>
1024+
%gep2.int = ptrtoint <2 x ptr> %gep2 to <2 x i64>
1025+
%d = sub <2 x i64> %gep2.int, %gep1.int
1026+
ret <2 x i64> %d
1027+
}

0 commit comments

Comments
 (0)