Skip to content

Commit c88697d

Browse files
committed
The patch fixes (base, index, offset) match.
Summary: Instead of matching: (a + i) + 1 -> (a + i, undef, 1) Now it matches: (a + i) + 1 -> (a, i, 1) Reviewers: rengolin Differential Revision: http://reviews.llvm.org/D26367 From: Evgeny Stupachenko <[email protected]> llvm-svn: 291012
1 parent f51b0d5 commit c88697d

File tree

2 files changed

+43
-9
lines changed

2 files changed

+43
-9
lines changed

llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4277,7 +4277,8 @@ struct BaseIndexOffset {
42774277
}
42784278

42794279
/// Parses tree in Ptr for base, index, offset addresses.
4280-
static BaseIndexOffset match(SDValue Ptr, SelectionDAG &DAG) {
4280+
static BaseIndexOffset match(SDValue Ptr, SelectionDAG &DAG,
4281+
int64_t PartialOffset = 0) {
42814282
bool IsIndexSignExt = false;
42824283

42834284
// Split up a folded GlobalAddress+Offset into its component parts.
@@ -4286,7 +4287,7 @@ struct BaseIndexOffset {
42864287
return BaseIndexOffset(DAG.getGlobalAddress(GA->getGlobal(),
42874288
SDLoc(GA),
42884289
GA->getValueType(0),
4289-
/*Offset=*/0,
4290+
/*Offset=*/PartialOffset,
42904291
/*isTargetGA=*/false,
42914292
GA->getTargetFlags()),
42924293
SDValue(),
@@ -4298,14 +4299,13 @@ struct BaseIndexOffset {
42984299
// instruction, then it could be just the BASE or everything else we don't
42994300
// know how to handle. Just use Ptr as BASE and give up.
43004301
if (Ptr->getOpcode() != ISD::ADD)
4301-
return BaseIndexOffset(Ptr, SDValue(), 0, IsIndexSignExt);
4302+
return BaseIndexOffset(Ptr, SDValue(), PartialOffset, IsIndexSignExt);
43024303

43034304
// We know that we have at least an ADD instruction. Try to pattern match
43044305
// the simple case of BASE + OFFSET.
43054306
if (isa<ConstantSDNode>(Ptr->getOperand(1))) {
43064307
int64_t Offset = cast<ConstantSDNode>(Ptr->getOperand(1))->getSExtValue();
4307-
return BaseIndexOffset(Ptr->getOperand(0), SDValue(), Offset,
4308-
IsIndexSignExt);
4308+
return match(Ptr->getOperand(0), DAG, Offset + PartialOffset);
43094309
}
43104310

43114311
// Inside a loop the current BASE pointer is calculated using an ADD and a
@@ -4314,7 +4314,7 @@ struct BaseIndexOffset {
43144314
// (i64 mul (i64 %induction_var)
43154315
// (i64 %element_size)))
43164316
if (Ptr->getOperand(1)->getOpcode() == ISD::MUL)
4317-
return BaseIndexOffset(Ptr, SDValue(), 0, IsIndexSignExt);
4317+
return BaseIndexOffset(Ptr, SDValue(), PartialOffset, IsIndexSignExt);
43184318

43194319
// Look at Base + Index + Offset cases.
43204320
SDValue Base = Ptr->getOperand(0);
@@ -4328,14 +4328,14 @@ struct BaseIndexOffset {
43284328

43294329
// Either the case of Base + Index (no offset) or something else.
43304330
if (IndexOffset->getOpcode() != ISD::ADD)
4331-
return BaseIndexOffset(Base, IndexOffset, 0, IsIndexSignExt);
4331+
return BaseIndexOffset(Base, IndexOffset, PartialOffset, IsIndexSignExt);
43324332

43334333
// Now we have the case of Base + Index + offset.
43344334
SDValue Index = IndexOffset->getOperand(0);
43354335
SDValue Offset = IndexOffset->getOperand(1);
43364336

43374337
if (!isa<ConstantSDNode>(Offset))
4338-
return BaseIndexOffset(Ptr, SDValue(), 0, IsIndexSignExt);
4338+
return BaseIndexOffset(Ptr, SDValue(), PartialOffset, IsIndexSignExt);
43394339

43404340
// Ignore signextends.
43414341
if (Index->getOpcode() == ISD::SIGN_EXTEND) {
@@ -4344,7 +4344,7 @@ struct BaseIndexOffset {
43444344
} else IsIndexSignExt = false;
43454345

43464346
int64_t Off = cast<ConstantSDNode>(Offset)->getSExtValue();
4347-
return BaseIndexOffset(Base, Index, Off, IsIndexSignExt);
4347+
return BaseIndexOffset(Base, Index, Off + PartialOffset, IsIndexSignExt);
43484348
}
43494349
};
43504350
} // namespace

llvm/test/CodeGen/X86/MergeConsecutiveStores.ll

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,40 @@ define void @MergeLoadStoreBaseIndexOffset(i64* %a, i8* %b, i8* %c, i32 %n) {
370370
ret void
371371
}
372372

373+
; Make sure that we merge the consecutive load/store sequence below and use a
374+
; word (16 bit) instead of a byte copy for complicated address calculation.
375+
; .
376+
; CHECK-LABEL: MergeLoadStoreBaseIndexOffsetComplicated:
377+
; BWON: movzwl (%{{.*}},%{{.*}}), %e[[REG:[a-z]+]]
378+
; BWOFF: movw (%{{.*}},%{{.*}}), %[[REG:[a-z]+]]
379+
; CHECK: movw %[[REG]], (%{{.*}})
380+
define void @MergeLoadStoreBaseIndexOffsetComplicated(i8* %a, i8* %b, i8* %c, i64 %n) {
381+
br label %1
382+
383+
; <label>:1
384+
%.09 = phi i64 [ 0, %0 ], [ %13, %1 ]
385+
%.08 = phi i8* [ %b, %0 ], [ %12, %1 ]
386+
%2 = load i8, i8* %.08, align 1
387+
%3 = sext i8 %2 to i64
388+
%4 = getelementptr inbounds i8, i8* %c, i64 %3
389+
%5 = load i8, i8* %4, align 1
390+
%6 = add nsw i64 %3, 1
391+
%7 = getelementptr inbounds i8, i8* %c, i64 %6
392+
%8 = load i8, i8* %7, align 1
393+
%9 = getelementptr inbounds i8, i8* %a, i64 %.09
394+
store i8 %5, i8* %9, align 1
395+
%10 = or i64 %.09, 1
396+
%11 = getelementptr inbounds i8, i8* %a, i64 %10
397+
store i8 %8, i8* %11, align 1
398+
%12 = getelementptr inbounds i8, i8* %.08, i64 1
399+
%13 = add nuw nsw i64 %.09, 2
400+
%14 = icmp slt i64 %13, %n
401+
br i1 %14, label %1, label %15
402+
403+
; <label>:15
404+
ret void
405+
}
406+
373407
; Make sure that we merge the consecutive load/store sequence below and use a
374408
; word (16 bit) instead of a byte copy even if there are intermediate sign
375409
; extensions.

0 commit comments

Comments
 (0)