The canonical form preferred by instcombine is to use 64-bit values for the index when it is a constant. We should try to do the same where possible in the loop vectoriser as this reduces churn in the compiler. It also makes other work easier, such as removing extra unnecessary passes on the RUN line in the test directory which I plan to do afterwards.
481 lines
17 KiB
LLVM
481 lines
17 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals none --version 5
|
|
; RUN: opt -passes=loop-vectorize -force-vector-width=4 -S %s | FileCheck %s
|
|
|
|
define void @const_fold_ptradd(ptr %dst, i64 %d) {
|
|
; CHECK-LABEL: define void @const_fold_ptradd(
|
|
; CHECK-SAME: ptr [[DST:%.*]], i64 [[D:%.*]]) {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: br label %[[VECTOR_PH:.*]]
|
|
; CHECK: [[VECTOR_PH]]:
|
|
; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
|
|
; CHECK: [[VECTOR_BODY]]:
|
|
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
|
|
; CHECK-NEXT: store i16 0, ptr [[DST]], align 2
|
|
; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[INDEX_NEXT]], 100
|
|
; CHECK-NEXT: br i1 [[TMP1]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
|
|
; CHECK: [[MIDDLE_BLOCK]]:
|
|
; CHECK-NEXT: br label %[[EXIT:.*]]
|
|
; CHECK: [[EXIT]]:
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
br label %loop.header
|
|
|
|
loop.header:
|
|
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
|
|
br i1 true, label %loop.latch, label %else
|
|
|
|
else:
|
|
br label %loop.latch
|
|
|
|
loop.latch:
|
|
%const.0 = phi i64 [ %d, %else ], [ 0, %loop.header ]
|
|
%gep = getelementptr i16, ptr %dst, i64 %const.0
|
|
store i16 0, ptr %gep, align 2
|
|
%iv.next = add i64 %iv, 1
|
|
%cmp = icmp ult i64 %iv.next, 100
|
|
br i1 %cmp, label %loop.header, label %exit
|
|
|
|
exit:
|
|
ret void
|
|
}
|
|
|
|
define void @const_fold_inbounds_ptradd(ptr %dst, i64 %d) {
|
|
; CHECK-LABEL: define void @const_fold_inbounds_ptradd(
|
|
; CHECK-SAME: ptr [[DST:%.*]], i64 [[D:%.*]]) {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: br label %[[VECTOR_PH:.*]]
|
|
; CHECK: [[VECTOR_PH]]:
|
|
; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
|
|
; CHECK: [[VECTOR_BODY]]:
|
|
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
|
|
; CHECK-NEXT: store i16 0, ptr [[DST]], align 2
|
|
; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[INDEX_NEXT]], 100
|
|
; CHECK-NEXT: br i1 [[TMP1]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP3:![0-9]+]]
|
|
; CHECK: [[MIDDLE_BLOCK]]:
|
|
; CHECK-NEXT: br label %[[EXIT:.*]]
|
|
; CHECK: [[EXIT]]:
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
br label %loop.header
|
|
|
|
loop.header:
|
|
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
|
|
br i1 true, label %loop.latch, label %else
|
|
|
|
else:
|
|
br label %loop.latch
|
|
|
|
loop.latch:
|
|
%const.0 = phi i64 [ %d, %else ], [ 0, %loop.header ]
|
|
%gep = getelementptr inbounds i16, ptr %dst, i64 %const.0
|
|
store i16 0, ptr %gep, align 2
|
|
%iv.next = add i64 %iv, 1
|
|
%cmp = icmp ult i64 %iv.next, 100
|
|
br i1 %cmp, label %loop.header, label %exit
|
|
|
|
exit:
|
|
ret void
|
|
}
|
|
|
|
define void @const_fold_select(ptr %dst, i64 %d) {
|
|
; CHECK-LABEL: define void @const_fold_select(
|
|
; CHECK-SAME: ptr [[DST:%.*]], i64 [[D:%.*]]) {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: br label %[[VECTOR_PH:.*]]
|
|
; CHECK: [[VECTOR_PH]]:
|
|
; CHECK-NEXT: [[TMP3:%.*]] = or i64 [[D]], 1
|
|
; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
|
|
; CHECK: [[VECTOR_BODY]]:
|
|
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
|
|
; CHECK-NEXT: store i64 [[TMP3]], ptr [[DST]], align 8
|
|
; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
|
|
; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i64 [[INDEX_NEXT]], 100
|
|
; CHECK-NEXT: br i1 [[TMP4]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]]
|
|
; CHECK: [[MIDDLE_BLOCK]]:
|
|
; CHECK-NEXT: br label %[[EXIT:.*]]
|
|
; CHECK: [[EXIT]]:
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
br label %loop.header
|
|
|
|
loop.header:
|
|
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
|
|
br i1 true, label %loop.latch, label %else
|
|
|
|
else:
|
|
br label %loop.latch
|
|
|
|
loop.latch:
|
|
%const.1 = phi i64 [ %d, %else ], [ 1, %loop.header ]
|
|
%or = or i64 %d, %const.1
|
|
store i64 %or, ptr %dst, align 8
|
|
%iv.next = add i64 %iv, 1
|
|
%cmp = icmp ult i64 %iv.next, 100
|
|
br i1 %cmp, label %loop.header, label %exit
|
|
|
|
exit:
|
|
ret void
|
|
}
|
|
|
|
define void @const_fold_add_sub_mul_ashr_lshr(ptr %dst, i64 %d) {
|
|
; CHECK-LABEL: define void @const_fold_add_sub_mul_ashr_lshr(
|
|
; CHECK-SAME: ptr [[DST:%.*]], i64 [[D:%.*]]) {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: br label %[[VECTOR_PH:.*]]
|
|
; CHECK: [[VECTOR_PH]]:
|
|
; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
|
|
; CHECK: [[VECTOR_BODY]]:
|
|
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
|
|
; CHECK-NEXT: store i64 1, ptr [[DST]], align 8
|
|
; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
|
|
; CHECK-NEXT: [[TMP6:%.*]] = icmp eq i64 [[INDEX_NEXT]], 100
|
|
; CHECK-NEXT: br i1 [[TMP6]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP5:![0-9]+]]
|
|
; CHECK: [[MIDDLE_BLOCK]]:
|
|
; CHECK-NEXT: br label %[[EXIT:.*]]
|
|
; CHECK: [[EXIT]]:
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
br label %loop.header
|
|
|
|
loop.header:
|
|
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
|
|
br i1 true, label %loop.latch, label %else
|
|
|
|
else:
|
|
br label %loop.latch
|
|
|
|
loop.latch:
|
|
%const.1 = phi i64 [ %d, %else ], [ 1, %loop.header ]
|
|
%add = add i64 2, %const.1
|
|
%sub = sub i64 %add, %const.1
|
|
%ashr = ashr i64 %sub, %const.1
|
|
%mul = mul i64 %ashr, 3
|
|
%lshr = lshr i64 %mul, %const.1
|
|
store i64 %lshr, ptr %dst, align 8
|
|
%iv.next = add i64 %iv, 1
|
|
%cmp = icmp ult i64 %iv.next, 100
|
|
br i1 %cmp, label %loop.header, label %exit
|
|
|
|
exit:
|
|
ret void
|
|
}
|
|
|
|
define void @const_fold_and_or_xor(ptr %dst, i64 %d) {
|
|
; CHECK-LABEL: define void @const_fold_and_or_xor(
|
|
; CHECK-SAME: ptr [[DST:%.*]], i64 [[D:%.*]]) {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: br label %[[VECTOR_PH:.*]]
|
|
; CHECK: [[VECTOR_PH]]:
|
|
; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
|
|
; CHECK: [[VECTOR_BODY]]:
|
|
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
|
|
; CHECK-NEXT: store i64 1, ptr [[DST]], align 8
|
|
; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
|
|
; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i64 [[INDEX_NEXT]], 100
|
|
; CHECK-NEXT: br i1 [[TMP4]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP6:![0-9]+]]
|
|
; CHECK: [[MIDDLE_BLOCK]]:
|
|
; CHECK-NEXT: br label %[[EXIT:.*]]
|
|
; CHECK: [[EXIT]]:
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
br label %loop.header
|
|
|
|
loop.header:
|
|
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
|
|
br i1 true, label %loop.latch, label %else
|
|
|
|
else:
|
|
br label %loop.latch
|
|
|
|
loop.latch:
|
|
%const.1 = phi i64 [ %d, %else ], [ 1, %loop.header ]
|
|
%or = or i64 2, %const.1
|
|
%and = and i64 %or, %const.1
|
|
%xor = and i64 %and, %const.1
|
|
store i64 %xor, ptr %dst, align 8
|
|
%iv.next = add i64 %iv, 1
|
|
%cmp = icmp ult i64 %iv.next, 100
|
|
br i1 %cmp, label %loop.header, label %exit
|
|
|
|
exit:
|
|
ret void
|
|
}
|
|
|
|
define void @const_fold_cmp_zext(ptr %dst, i64 %d) {
|
|
; CHECK-LABEL: define void @const_fold_cmp_zext(
|
|
; CHECK-SAME: ptr [[DST:%.*]], i64 [[D:%.*]]) {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: br label %[[VECTOR_PH:.*]]
|
|
; CHECK: [[VECTOR_PH]]:
|
|
; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
|
|
; CHECK: [[VECTOR_BODY]]:
|
|
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
|
|
; CHECK-NEXT: store i8 1, ptr [[DST]], align 1
|
|
; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
|
|
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i64 [[INDEX_NEXT]], 100
|
|
; CHECK-NEXT: br i1 [[TMP3]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP7:![0-9]+]]
|
|
; CHECK: [[MIDDLE_BLOCK]]:
|
|
; CHECK-NEXT: br label %[[EXIT:.*]]
|
|
; CHECK: [[EXIT]]:
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
br label %loop.header
|
|
|
|
loop.header:
|
|
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
|
|
br i1 true, label %loop.latch, label %else
|
|
|
|
else:
|
|
br label %loop.latch
|
|
|
|
loop.latch:
|
|
%const.1 = phi i64 [ %d, %else ], [ 1, %loop.header ]
|
|
%val = icmp ugt i64 2, %const.1
|
|
%zext = zext i1 %val to i8
|
|
store i8 %zext, ptr %dst, align 1
|
|
%iv.next = add i64 %iv, 1
|
|
%cmp = icmp ult i64 %iv.next, 100
|
|
br i1 %cmp, label %loop.header, label %exit
|
|
|
|
exit:
|
|
ret void
|
|
}
|
|
|
|
define void @const_fold_trunc(ptr %dst, i64 %d) {
|
|
; CHECK-LABEL: define void @const_fold_trunc(
|
|
; CHECK-SAME: ptr [[DST:%.*]], i64 [[D:%.*]]) {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: br label %[[VECTOR_PH:.*]]
|
|
; CHECK: [[VECTOR_PH]]:
|
|
; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
|
|
; CHECK: [[VECTOR_BODY]]:
|
|
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
|
|
; CHECK-NEXT: store i16 0, ptr [[DST]], align 2
|
|
; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[INDEX_NEXT]], 100
|
|
; CHECK-NEXT: br i1 [[TMP2]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP8:![0-9]+]]
|
|
; CHECK: [[MIDDLE_BLOCK]]:
|
|
; CHECK-NEXT: br label %[[EXIT:.*]]
|
|
; CHECK: [[EXIT]]:
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
br label %loop.header
|
|
|
|
loop.header:
|
|
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
|
|
br i1 true, label %loop.latch, label %else
|
|
|
|
else:
|
|
br label %loop.latch
|
|
|
|
loop.latch:
|
|
%const.0 = phi i64 [ %d, %else ], [ 0, %loop.header ]
|
|
%trunc = trunc i64 %const.0 to i16
|
|
store i16 %trunc, ptr %dst, align 2
|
|
%iv.next = add i64 %iv, 1
|
|
%cmp = icmp ult i64 %iv.next, 100
|
|
br i1 %cmp, label %loop.header, label %exit
|
|
|
|
exit:
|
|
ret void
|
|
}
|
|
|
|
define void @const_fold_binaryintrinsic(ptr %dst, i64 %d) {
|
|
; CHECK-LABEL: define void @const_fold_binaryintrinsic(
|
|
; CHECK-SAME: ptr [[DST:%.*]], i64 [[D:%.*]]) {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: br label %[[VECTOR_PH:.*]]
|
|
; CHECK: [[VECTOR_PH]]:
|
|
; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
|
|
; CHECK: [[VECTOR_BODY]]:
|
|
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
|
|
; CHECK-NEXT: store i64 3, ptr [[DST]], align 2
|
|
; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[INDEX_NEXT]], 100
|
|
; CHECK-NEXT: br i1 [[TMP2]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP9:![0-9]+]]
|
|
; CHECK: [[MIDDLE_BLOCK]]:
|
|
; CHECK-NEXT: br label %[[EXIT:.*]]
|
|
; CHECK: [[EXIT]]:
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
br label %loop
|
|
|
|
loop:
|
|
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
|
|
%const.0 = xor i64 %d, %d
|
|
%trunc = call i64 @llvm.umax.i64(i64 %const.0, i64 3)
|
|
store i64 %trunc, ptr %dst, align 2
|
|
%iv.next = add i64 %iv, 1
|
|
%cmp = icmp ult i64 %iv.next, 100
|
|
br i1 %cmp, label %loop, label %exit
|
|
|
|
exit:
|
|
ret void
|
|
}
|
|
|
|
define void @const_fold_widegep(ptr noalias %A, ptr noalias %B, i64 %d) {
|
|
; CHECK-LABEL: define void @const_fold_widegep(
|
|
; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], i64 [[D:%.*]]) {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: br label %[[VECTOR_PH:.*]]
|
|
; CHECK: [[VECTOR_PH]]:
|
|
; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
|
|
; CHECK: [[VECTOR_BODY]]:
|
|
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
|
|
; CHECK-NEXT: store ptr [[A]], ptr [[B]], align 8
|
|
; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = icmp eq i64 [[INDEX_NEXT]], 100
|
|
; CHECK-NEXT: br i1 [[TMP0]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP10:![0-9]+]]
|
|
; CHECK: [[MIDDLE_BLOCK]]:
|
|
; CHECK-NEXT: br label %[[EXIT:.*]]
|
|
; CHECK: [[EXIT]]:
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
br label %loop
|
|
|
|
loop:
|
|
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
|
|
%const.0 = xor i64 %d, %d
|
|
%gep.A = getelementptr i64, ptr %A, i64 %const.0
|
|
%gep.B = getelementptr i64, ptr %B, i64 %const.0
|
|
store ptr %gep.A, ptr %gep.B
|
|
%iv.next = add nuw nsw i64 %iv, 1
|
|
%exit.cond = icmp ult i64 %iv.next, 100
|
|
br i1 %exit.cond, label %loop, label %exit
|
|
|
|
exit:
|
|
ret void
|
|
}
|
|
|
|
; The test intentionally uses a large number of live-ins to guard against a
|
|
; use-after-free when reallocating
|
|
; (https://github.com/llvm/llvm-project/issues/173222).
|
|
define void @unused_live_ins_in_preheader(ptr %dst, ptr %src) {
|
|
; CHECK-LABEL: define void @unused_live_ins_in_preheader(
|
|
; CHECK-SAME: ptr [[DST:%.*]], ptr [[SRC:%.*]]) {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i8 0, 0
|
|
; CHECK-NEXT: [[ZEXT1:%.*]] = zext i1 false to i32
|
|
; CHECK-NEXT: [[TRUNC1:%.*]] = trunc i64 0 to i16
|
|
; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i16 0, 0
|
|
; CHECK-NEXT: [[SEL1:%.*]] = select i1 false, i16 0, i16 0
|
|
; CHECK-NEXT: [[ZEXT2:%.*]] = zext i16 0 to i32
|
|
; CHECK-NEXT: [[LSHR1:%.*]] = lshr i32 0, 0
|
|
; CHECK-NEXT: [[TRUNC2:%.*]] = trunc i32 0 to i16
|
|
; CHECK-NEXT: [[XOR1:%.*]] = xor i16 0, 0
|
|
; CHECK-NEXT: [[ZEXT3:%.*]] = zext i16 0 to i32
|
|
; CHECK-NEXT: [[LD:%.*]] = load i32, ptr [[SRC]], align 4
|
|
; CHECK-NEXT: [[CMP3:%.*]] = icmp sgt i32 0, 0
|
|
; CHECK-NEXT: [[LSHR2:%.*]] = lshr i32 0, 0
|
|
; CHECK-NEXT: [[CMP4:%.*]] = icmp ne i32 0, 0
|
|
; CHECK-NEXT: [[SEL2:%.*]] = select i1 false, i1 false, i1 false
|
|
; CHECK-NEXT: [[SHL1:%.*]] = shl i32 0, 0
|
|
; CHECK-NEXT: [[SEL3:%.*]] = select i1 false, i32 0, i32 0
|
|
; CHECK-NEXT: [[SEXT1:%.*]] = sext i8 0 to i32
|
|
; CHECK-NEXT: [[CMP5:%.*]] = icmp eq i32 0, 0
|
|
; CHECK-NEXT: [[ZEXT4:%.*]] = zext i32 0 to i64
|
|
; CHECK-NEXT: [[SUB1:%.*]] = sub i64 0, 0
|
|
; CHECK-NEXT: [[SEXT2:%.*]] = sext i8 0 to i64
|
|
; CHECK-NEXT: [[AND1:%.*]] = and i64 0, 0
|
|
; CHECK-NEXT: [[CMP6:%.*]] = icmp ne i64 0, 0
|
|
; CHECK-NEXT: [[ZEXT5:%.*]] = zext i1 false to i16
|
|
; CHECK-NEXT: [[CMP7:%.*]] = icmp eq i16 0, 0
|
|
; CHECK-NEXT: br label %[[VECTOR_PH:.*]]
|
|
; CHECK: [[VECTOR_PH]]:
|
|
; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
|
|
; CHECK: [[VECTOR_BODY]]:
|
|
; CHECK-NEXT: [[INDEX:%.*]] = phi i32 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[PRED_STORE_CONTINUE6:.*]] ]
|
|
; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i8> [ <i8 0, i8 1, i8 2, i8 3>, %[[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], %[[PRED_STORE_CONTINUE6]] ]
|
|
; CHECK-NEXT: [[TMP0:%.*]] = icmp ule <4 x i8> [[VEC_IND]], splat (i8 8)
|
|
; CHECK-NEXT: [[TMP1:%.*]] = extractelement <4 x i1> [[TMP0]], i64 0
|
|
; CHECK-NEXT: br i1 [[TMP1]], label %[[PRED_STORE_IF:.*]], label %[[PRED_STORE_CONTINUE:.*]]
|
|
; CHECK: [[PRED_STORE_IF]]:
|
|
; CHECK-NEXT: [[TMP3:%.*]] = getelementptr i32, ptr [[DST]], i32 [[INDEX]]
|
|
; CHECK-NEXT: store i32 [[INDEX]], ptr [[TMP3]], align 8
|
|
; CHECK-NEXT: br label %[[PRED_STORE_CONTINUE]]
|
|
; CHECK: [[PRED_STORE_CONTINUE]]:
|
|
; CHECK-NEXT: [[TMP4:%.*]] = extractelement <4 x i1> [[TMP0]], i64 1
|
|
; CHECK-NEXT: br i1 [[TMP4]], label %[[PRED_STORE_IF1:.*]], label %[[PRED_STORE_CONTINUE2:.*]]
|
|
; CHECK: [[PRED_STORE_IF1]]:
|
|
; CHECK-NEXT: [[TMP5:%.*]] = add i32 [[INDEX]], 1
|
|
; CHECK-NEXT: [[TMP6:%.*]] = getelementptr i32, ptr [[DST]], i32 [[TMP5]]
|
|
; CHECK-NEXT: store i32 [[TMP5]], ptr [[TMP6]], align 8
|
|
; CHECK-NEXT: br label %[[PRED_STORE_CONTINUE2]]
|
|
; CHECK: [[PRED_STORE_CONTINUE2]]:
|
|
; CHECK-NEXT: [[TMP7:%.*]] = extractelement <4 x i1> [[TMP0]], i64 2
|
|
; CHECK-NEXT: br i1 [[TMP7]], label %[[PRED_STORE_IF3:.*]], label %[[PRED_STORE_CONTINUE4:.*]]
|
|
; CHECK: [[PRED_STORE_IF3]]:
|
|
; CHECK-NEXT: [[TMP8:%.*]] = add i32 [[INDEX]], 2
|
|
; CHECK-NEXT: [[TMP9:%.*]] = getelementptr i32, ptr [[DST]], i32 [[TMP8]]
|
|
; CHECK-NEXT: store i32 [[TMP8]], ptr [[TMP9]], align 8
|
|
; CHECK-NEXT: br label %[[PRED_STORE_CONTINUE4]]
|
|
; CHECK: [[PRED_STORE_CONTINUE4]]:
|
|
; CHECK-NEXT: [[TMP10:%.*]] = extractelement <4 x i1> [[TMP0]], i64 3
|
|
; CHECK-NEXT: br i1 [[TMP10]], label %[[PRED_STORE_IF5:.*]], label %[[PRED_STORE_CONTINUE6]]
|
|
; CHECK: [[PRED_STORE_IF5]]:
|
|
; CHECK-NEXT: [[TMP11:%.*]] = add i32 [[INDEX]], 3
|
|
; CHECK-NEXT: [[TMP12:%.*]] = getelementptr i32, ptr [[DST]], i32 [[TMP11]]
|
|
; CHECK-NEXT: store i32 [[TMP11]], ptr [[TMP12]], align 8
|
|
; CHECK-NEXT: br label %[[PRED_STORE_CONTINUE6]]
|
|
; CHECK: [[PRED_STORE_CONTINUE6]]:
|
|
; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 4
|
|
; CHECK-NEXT: [[VEC_IND_NEXT]] = add <4 x i8> [[VEC_IND]], splat (i8 4)
|
|
; CHECK-NEXT: [[TMP13:%.*]] = icmp eq i32 [[INDEX_NEXT]], 12
|
|
; CHECK-NEXT: br i1 [[TMP13]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP11:![0-9]+]]
|
|
; CHECK: [[MIDDLE_BLOCK]]:
|
|
; CHECK-NEXT: br label %[[EXIT:.*]]
|
|
; CHECK: [[EXIT]]:
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
%cmp1 = icmp ne i8 0, 0
|
|
%zext1 = zext i1 false to i32
|
|
%trunc1 = trunc i64 0 to i16
|
|
%cmp2 = icmp sgt i16 0, 0
|
|
%sel1 = select i1 false, i16 0, i16 0
|
|
%zext2 = zext i16 0 to i32
|
|
%lshr1 = lshr i32 0, 0
|
|
%trunc2 = trunc i32 0 to i16
|
|
%xor1 = xor i16 0, 0
|
|
%zext3 = zext i16 0 to i32
|
|
%ld = load i32, ptr %src, align 4
|
|
%cmp3 = icmp sgt i32 0, 0
|
|
%lshr2 = lshr i32 0, 0
|
|
%cmp4 = icmp ne i32 0, 0
|
|
%sel2 = select i1 false, i1 false, i1 false
|
|
%shl1 = shl i32 0, 0
|
|
%sel3 = select i1 false, i32 0, i32 0
|
|
%sext1 = sext i8 0 to i32
|
|
%cmp5 = icmp eq i32 0, 0
|
|
%zext4 = zext i32 0 to i64
|
|
%sub1 = sub i64 0, 0
|
|
%sext2 = sext i8 0 to i64
|
|
%and1 = and i64 0, 0
|
|
%cmp6 = icmp ne i64 0, 0
|
|
%zext5 = zext i1 false to i16
|
|
%cmp7 = icmp eq i16 0, 0
|
|
br label %loop
|
|
|
|
loop:
|
|
%iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
|
|
%gep = getelementptr i32, ptr %dst, i32 %iv
|
|
store i32 %iv, ptr %gep, align 8
|
|
%iv.next = add i32 %iv, 1
|
|
%ec = icmp eq i32 %iv, 8
|
|
br i1 %ec, label %exit, label %loop
|
|
|
|
exit:
|
|
ret void
|
|
}
|