Files
clang-p2996/llvm/test/Transforms/PhaseOrdering/X86/pr38280.ll
Simon Pilgrim 08d153d806 [ValueTracking] computeKnownBits - attempt to use a branch condition feeding a phi to improve known bits range (PR38280)
If computeKnownBits encounters a phi node, and we fail to determine any known bits through direct analysis, see if the incoming value is part of a branch condition feeding the phi.

Handle cases where icmp(IncomingValue PRED Constant) is driving a branch instruction feeding that phi node - at the moment this only handles EQ/ULT/ULE predicate cases as they are the most straightforward to handle and most likely for branch-loop 'max upper bound' cases - we can extend this if/when necessary.

I investigated a more general icmp(LHS PRED RHS) KnownBits system, but the hard limits we put on value tracking depth through phi nodes meant that we were mainly catching constants anyhow.

Fixes the pointless vectorization in PR38280 / Issue #37628 (excessive unrolling still needs handling though)

Differential Revision: https://reviews.llvm.org/D131838
2022-08-16 16:54:44 +01:00

107 lines
5.9 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -O2 -S -mtriple=x86_64-- -mattr=+sse2 < %s | FileCheck %s
; RUN: opt -O2 -S -mtriple=x86_64-- -mattr=+avx2 < %s | FileCheck %s
; PR38280 / Issue #37628
define void @apply_delta(ptr nocapture noundef %dst, ptr nocapture noundef readonly %src, i64 noundef %neg_offs, i64 noundef %count) {
; CHECK-LABEL: @apply_delta(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP21:%.*]] = icmp ugt i64 [[COUNT:%.*]], 7
; CHECK-NEXT: br i1 [[CMP21]], label [[WHILE_BODY:%.*]], label [[WHILE_COND3_PREHEADER:%.*]]
; CHECK: while.cond3.preheader:
; CHECK-NEXT: [[COUNT_ADDR_0_LCSSA:%.*]] = phi i64 [ [[COUNT]], [[ENTRY:%.*]] ], [ [[SUB:%.*]], [[WHILE_BODY]] ]
; CHECK-NEXT: [[SRC_ADDR_0_LCSSA:%.*]] = phi ptr [ [[SRC:%.*]], [[ENTRY]] ], [ [[ADD_PTR2:%.*]], [[WHILE_BODY]] ]
; CHECK-NEXT: [[DST_ADDR_0_LCSSA:%.*]] = phi ptr [ [[DST:%.*]], [[ENTRY]] ], [ [[ADD_PTR1:%.*]], [[WHILE_BODY]] ]
; CHECK-NEXT: [[TOBOOL_NOT27:%.*]] = icmp eq i64 [[COUNT_ADDR_0_LCSSA]], 0
; CHECK-NEXT: br i1 [[TOBOOL_NOT27]], label [[WHILE_END9:%.*]], label [[WHILE_BODY4:%.*]]
; CHECK: while.body:
; CHECK-NEXT: [[DST_ADDR_024:%.*]] = phi ptr [ [[ADD_PTR1]], [[WHILE_BODY]] ], [ [[DST]], [[ENTRY]] ]
; CHECK-NEXT: [[SRC_ADDR_023:%.*]] = phi ptr [ [[ADD_PTR2]], [[WHILE_BODY]] ], [ [[SRC]], [[ENTRY]] ]
; CHECK-NEXT: [[COUNT_ADDR_022:%.*]] = phi i64 [ [[SUB]], [[WHILE_BODY]] ], [ [[COUNT]], [[ENTRY]] ]
; CHECK-NEXT: [[TMP0:%.*]] = load <8 x i8>, ptr [[SRC_ADDR_023]], align 1
; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, ptr [[DST_ADDR_024]], i64 [[NEG_OFFS:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = load <8 x i8>, ptr [[ADD_PTR]], align 1
; CHECK-NEXT: [[ADD:%.*]] = add <8 x i8> [[TMP1]], [[TMP0]]
; CHECK-NEXT: store <8 x i8> [[ADD]], ptr [[DST_ADDR_024]], align 1
; CHECK-NEXT: [[ADD_PTR1]] = getelementptr inbounds i8, ptr [[DST_ADDR_024]], i64 8
; CHECK-NEXT: [[ADD_PTR2]] = getelementptr inbounds i8, ptr [[SRC_ADDR_023]], i64 8
; CHECK-NEXT: [[SUB]] = add i64 [[COUNT_ADDR_022]], -8
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i64 [[SUB]], 7
; CHECK-NEXT: br i1 [[CMP]], label [[WHILE_BODY]], label [[WHILE_COND3_PREHEADER]]
; CHECK: while.body4:
; CHECK-NEXT: [[DST_ADDR_130:%.*]] = phi ptr [ [[INCDEC_PTR:%.*]], [[WHILE_BODY4]] ], [ [[DST_ADDR_0_LCSSA]], [[WHILE_COND3_PREHEADER]] ]
; CHECK-NEXT: [[SRC_ADDR_129:%.*]] = phi ptr [ [[INCDEC_PTR8:%.*]], [[WHILE_BODY4]] ], [ [[SRC_ADDR_0_LCSSA]], [[WHILE_COND3_PREHEADER]] ]
; CHECK-NEXT: [[COUNT_ADDR_128:%.*]] = phi i64 [ [[DEC:%.*]], [[WHILE_BODY4]] ], [ [[COUNT_ADDR_0_LCSSA]], [[WHILE_COND3_PREHEADER]] ]
; CHECK-NEXT: [[DEC]] = add i64 [[COUNT_ADDR_128]], -1
; CHECK-NEXT: [[TMP2:%.*]] = load i8, ptr [[SRC_ADDR_129]], align 1
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[DST_ADDR_130]], i64 [[NEG_OFFS]]
; CHECK-NEXT: [[TMP3:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
; CHECK-NEXT: [[ADD6:%.*]] = add i8 [[TMP3]], [[TMP2]]
; CHECK-NEXT: store i8 [[ADD6]], ptr [[DST_ADDR_130]], align 1
; CHECK-NEXT: [[INCDEC_PTR]] = getelementptr inbounds i8, ptr [[DST_ADDR_130]], i64 1
; CHECK-NEXT: [[INCDEC_PTR8]] = getelementptr inbounds i8, ptr [[SRC_ADDR_129]], i64 1
; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i64 [[DEC]], 0
; CHECK-NEXT: br i1 [[TOBOOL_NOT]], label [[WHILE_END9]], label [[WHILE_BODY4]], !llvm.loop [[LOOP0:![0-9]+]]
; CHECK: while.end9:
; CHECK-NEXT: ret void
;
entry:
%cmp21 = icmp ugt i64 %count, 7
br i1 %cmp21, label %while.body.preheader, label %while.cond3.preheader
while.body.preheader:
br label %while.body
while.cond3.preheader.loopexit:
%add.ptr1.lcssa = phi ptr [ %add.ptr1, %while.body ]
%add.ptr2.lcssa = phi ptr [ %add.ptr2, %while.body ]
%sub.lcssa = phi i64 [ %sub, %while.body ]
br label %while.cond3.preheader
while.cond3.preheader:
%count.addr.0.lcssa = phi i64 [ %count, %entry ], [ %sub.lcssa, %while.cond3.preheader.loopexit ]
%src.addr.0.lcssa = phi ptr [ %src, %entry ], [ %add.ptr2.lcssa, %while.cond3.preheader.loopexit ]
%dst.addr.0.lcssa = phi ptr [ %dst, %entry ], [ %add.ptr1.lcssa, %while.cond3.preheader.loopexit ]
%tobool.not27 = icmp eq i64 %count.addr.0.lcssa, 0
br i1 %tobool.not27, label %while.end9, label %while.body4.preheader
while.body4.preheader:
br label %while.body4
while.body:
%dst.addr.024 = phi ptr [ %add.ptr1, %while.body ], [ %dst, %while.body.preheader ]
%src.addr.023 = phi ptr [ %add.ptr2, %while.body ], [ %src, %while.body.preheader ]
%count.addr.022 = phi i64 [ %sub, %while.body ], [ %count, %while.body.preheader ]
%0 = load <8 x i8>, ptr %src.addr.023, align 1
%add.ptr = getelementptr inbounds i8, ptr %dst.addr.024, i64 %neg_offs
%1 = load <8 x i8>, ptr %add.ptr, align 1
%add = add <8 x i8> %1, %0
store <8 x i8> %add, ptr %dst.addr.024, align 1
%add.ptr1 = getelementptr inbounds i8, ptr %dst.addr.024, i64 8
%add.ptr2 = getelementptr inbounds i8, ptr %src.addr.023, i64 8
%sub = add i64 %count.addr.022, -8
%cmp = icmp ugt i64 %sub, 7
br i1 %cmp, label %while.body, label %while.cond3.preheader.loopexit
while.body4:
%dst.addr.130 = phi ptr [ %incdec.ptr, %while.body4 ], [ %dst.addr.0.lcssa, %while.body4.preheader ]
%src.addr.129 = phi ptr [ %incdec.ptr8, %while.body4 ], [ %src.addr.0.lcssa, %while.body4.preheader ]
%count.addr.128 = phi i64 [ %dec, %while.body4 ], [ %count.addr.0.lcssa, %while.body4.preheader ]
%dec = add i64 %count.addr.128, -1
%2 = load i8, ptr %src.addr.129, align 1
%arrayidx = getelementptr inbounds i8, ptr %dst.addr.130, i64 %neg_offs
%3 = load i8, ptr %arrayidx, align 1
%add6 = add i8 %3, %2
store i8 %add6, ptr %dst.addr.130, align 1
%incdec.ptr = getelementptr inbounds i8, ptr %dst.addr.130, i64 1
%incdec.ptr8 = getelementptr inbounds i8, ptr %src.addr.129, i64 1
%tobool.not = icmp eq i64 %dec, 0
br i1 %tobool.not, label %while.end9.loopexit, label %while.body4
while.end9.loopexit:
br label %while.end9
while.end9:
ret void
}