1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
;=========================== begin_copyright_notice ============================
;
; Copyright (C) 2024 Intel Corporation
;
; SPDX-License-Identifier: MIT
;
;============================ end_copyright_notice =============================
; RUN: igc_opt -remove-loop-dependency -S %s 2>&1 | FileCheck %s
; Test checks the basic functionality of the pass
define spir_kernel void @test(i32 %index) {
entry:
br label %header
header: ; preds = %header, %entry
; CHECK: [[VEC_INORDER_1:%.*]] = phi <4 x i32> [ zeroinitializer, [[ENTRY:%.*]] ], [ zeroinitializer, %header ]
; CHECK-NEXT: [[VEC_OUTORDER_1:%.*]] = phi <4 x i32> [ zeroinitializer, [[ENTRY]] ], [ zeroinitializer, %header ]
; CHECK-NEXT: [[VEC_PARTIAL_1:%.*]] = phi <4 x i32> [ zeroinitializer, [[ENTRY]] ], [ zeroinitializer, %header ]
; CHECK-NEXT: [[VEC_SAMEIND_1:%.*]] = phi <4 x i32> [ zeroinitializer, [[ENTRY]] ], [ zeroinitializer, %header ]
; CHECK-NEXT: [[VEC_USED_1:%.*]] = phi <4 x i32> [ zeroinitializer, [[ENTRY]] ], [ zeroinitializer, %header ]
; CHECK-NEXT: [[VEC_NOTLOOP_1:%.*]] = phi <4 x i32> [ zeroinitializer, [[ENTRY]] ], [ zeroinitializer, %header ]
; CHECK-NEXT: [[VEC_NOTCONSTIND_1:%.*]] = phi <4 x i32> [ zeroinitializer, [[ENTRY]] ], [ zeroinitializer, %header ]
; CHECK-NEXT: [[VEC_OUTOFRANGE_1:%.*]] = phi <4 x i32> [ zeroinitializer, [[ENTRY]] ], [ zeroinitializer, %header ]
; CHECK-NEXT: [[SCALAR:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ 0, %header ]
; CHECK-NEXT: [[VEC_NOTINSERT_1:%.*]] = phi <4 x i32> [ zeroinitializer, [[ENTRY]] ], [ zeroinitializer, %header ]
%vec.inorder.1 = phi <4 x i32> [ zeroinitializer, %entry ], [ zeroinitializer, %header ]
%vec.outorder.1 = phi <4 x i32> [ zeroinitializer, %entry ], [ zeroinitializer, %header ]
%vec.partial.1 = phi <4 x i32> [ zeroinitializer, %entry ], [ zeroinitializer, %header ]
%vec.sameind.1 = phi <4 x i32> [ zeroinitializer, %entry ], [ zeroinitializer, %header ]
%vec.used.1 = phi <4 x i32> [ zeroinitializer, %entry ], [ zeroinitializer, %header ]
%vec.notloop.1 = phi <4 x i32> [ zeroinitializer, %entry ], [ zeroinitializer, %header ]
%vec.notconstind.1 = phi <4 x i32> [ zeroinitializer, %entry ], [ zeroinitializer, %header ]
%vec.outofrange.1 = phi <4 x i32> [ zeroinitializer, %entry ], [ zeroinitializer, %header ]
%scalar = phi i32 [ 0, %entry ], [ 0, %header ]
%vec.notinsert.1 = phi <4 x i32> [ zeroinitializer, %entry ], [ zeroinitializer, %header ]
; whole vector is overwritten, so can replace with undef
; CHECK: [[VEC_INORDER_2:%.*]] = insertelement <4 x i32> undef, i32 5, i32 0
; CHECK-NEXT: [[VEC_INORDER_3:%.*]] = insertelement <4 x i32> [[VEC_INORDER_2]], i32 5, i32 1
; CHECK-NEXT: [[VEC_INORDER_4:%.*]] = insertelement <4 x i32> [[VEC_INORDER_3]], i32 5, i32 2
; CHECK-NEXT: [[VEC_INORDER_5:%.*]] = insertelement <4 x i32> [[VEC_INORDER_4]], i32 5, i32 3
%vec.inorder.2 = insertelement <4 x i32> %vec.inorder.1, i32 5, i32 0
%vec.inorder.3 = insertelement <4 x i32> %vec.inorder.2, i32 5, i32 1
%vec.inorder.4 = insertelement <4 x i32> %vec.inorder.3, i32 5, i32 2
%vec.inorder.5 = insertelement <4 x i32> %vec.inorder.4, i32 5, i32 3
; not whole vector is overwritten
; CHECK: [[VEC_OUTOFRANGE_2:%.*]] = insertelement <4 x i32> [[VEC_OUTOFRANGE_1]], i32 5, i32 0
; CHECK-NEXT: [[VEC_OUTOFRANGE_3:%.*]] = insertelement <4 x i32> [[VEC_OUTOFRANGE_2]], i32 5, i32 1
; CHECK-NEXT: [[VEC_OUTOFRANGE_4:%.*]] = insertelement <4 x i32> [[VEC_OUTOFRANGE_3]], i32 5, i32 2
; CHECK-NEXT: [[VEC_OUTOFRANGE_5:%.*]] = insertelement <4 x i32> [[VEC_OUTOFRANGE_4]], i32 5, i32 5
%vec.outofrange.2 = insertelement <4 x i32> %vec.outofrange.1, i32 5, i32 0
%vec.outofrange.3 = insertelement <4 x i32> %vec.outofrange.2, i32 5, i32 1
%vec.outofrange.4 = insertelement <4 x i32> %vec.outofrange.3, i32 5, i32 2
%vec.outofrange.5 = insertelement <4 x i32> %vec.outofrange.4, i32 5, i32 5
; we don't know if whole vector is overwritten
; CHECK: [[VEC_NOTCONSTIND_2:%.*]] = insertelement <4 x i32> [[VEC_NOTCONSTIND_1]], i32 5, i32 0
; CHECK-NEXT: [[VEC_NOTCONSTIND_3:%.*]] = insertelement <4 x i32> [[VEC_NOTCONSTIND_2]], i32 5, i32 1
; CHECK-NEXT: [[VEC_NOTCONSTIND_4:%.*]] = insertelement <4 x i32> [[VEC_NOTCONSTIND_3]], i32 5, i32 [[INDEX:%.*]]
; CHECK-NEXT: [[VEC_NOTCONSTIND_5:%.*]] = insertelement <4 x i32> [[VEC_NOTCONSTIND_4]], i32 5, i32 3
%vec.notconstind.2 = insertelement <4 x i32> %vec.notconstind.1, i32 5, i32 0
%vec.notconstind.3 = insertelement <4 x i32> %vec.notconstind.2, i32 5, i32 1
%vec.notconstind.4 = insertelement <4 x i32> %vec.notconstind.3, i32 5, i32 %index
%vec.notconstind.5 = insertelement <4 x i32> %vec.notconstind.4, i32 5, i32 3
; whole vector is overwritten, just different order of indexes, replace with undef
; CHECK: [[VEC_OUTORDER_2:%.*]] = insertelement <4 x i32> undef, i32 6, i32 2
; CHECK-NEXT: [[VEC_OUTORDER_3:%.*]] = insertelement <4 x i32> [[VEC_OUTORDER_2]], i32 6, i32 0
; CHECK-NEXT: [[VEC_OUTORDER_4:%.*]] = insertelement <4 x i32> [[VEC_OUTORDER_3]], i32 6, i32 3
; CHECK-NEXT: [[VEC_OUTORDER_5:%.*]] = insertelement <4 x i32> [[VEC_OUTORDER_4]], i32 6, i32 1
%vec.outorder.2 = insertelement <4 x i32> %vec.outorder.1, i32 6, i32 2
%vec.outorder.3 = insertelement <4 x i32> %vec.outorder.2, i32 6, i32 0
%vec.outorder.4 = insertelement <4 x i32> %vec.outorder.3, i32 6, i32 3
%vec.outorder.5 = insertelement <4 x i32> %vec.outorder.4, i32 6, i32 1
; not whole vector is overwritten
; CHECK: [[VEC_PARTIAL_2:%.*]] = insertelement <4 x i32> [[VEC_PARTIAL_1]], i32 5, i32 0
; CHECK-NEXT: [[VEC_PARTIAL_3:%.*]] = insertelement <4 x i32> [[VEC_PARTIAL_2]], i32 5, i32 1
; CHECK-NEXT: [[VEC_PARTIAL_4:%.*]] = insertelement <4 x i32> [[VEC_PARTIAL_3]], i32 5, i32 2
%vec.partial.2 = insertelement <4 x i32> %vec.partial.1, i32 5, i32 0
%vec.partial.3 = insertelement <4 x i32> %vec.partial.2, i32 5, i32 1
%vec.partial.4 = insertelement <4 x i32> %vec.partial.3, i32 5, i32 2
; not whole vector is overwritten
; CHECK: [[VEC_SAMEIND_2:%.*]] = insertelement <4 x i32> [[VEC_SAMEIND_1]], i32 5, i32 0
; CHECK-NEXT: [[VEC_SAMEIND_3:%.*]] = insertelement <4 x i32> [[VEC_SAMEIND_2]], i32 5, i32 1
; CHECK-NEXT: [[VEC_SAMEIND_4:%.*]] = insertelement <4 x i32> [[VEC_SAMEIND_3]], i32 5, i32 3
; CHECK-NEXT: [[VEC_SAMEIND_5:%.*]] = insertelement <4 x i32> [[VEC_SAMEIND_4]], i32 5, i32 3
%vec.sameind.2 = insertelement <4 x i32> %vec.sameind.1, i32 5, i32 0
%vec.sameind.3 = insertelement <4 x i32> %vec.sameind.2, i32 5, i32 1
%vec.sameind.4 = insertelement <4 x i32> %vec.sameind.3, i32 5, i32 3
%vec.sameind.5 = insertelement <4 x i32> %vec.sameind.4, i32 5, i32 3
; vector may be used in the loop before it is overwritten
; CHECK: [[VEC_USED_2:%.*]] = insertelement <4 x i32> [[VEC_USED_1]], i32 5, i32 0
; CHECK-NEXT: [[VEC_USED_3:%.*]] = insertelement <4 x i32> [[VEC_USED_2]], i32 5, i32 1
; CHECK-NEXT: [[VEC_USED_4:%.*]] = insertelement <4 x i32> [[VEC_USED_3]], i32 5, i32 2
; CHECK-NEXT: [[VEC_USED_5:%.*]] = insertelement <4 x i32> [[VEC_USED_4]], i32 5, i32 3
; CHECK-NEXT: [[USED_HERE:%.*]] = extractelement <4 x i32> [[VEC_USED_4]], i32 3
%vec.used.2 = insertelement <4 x i32> %vec.used.1, i32 5, i32 0
%vec.used.3 = insertelement <4 x i32> %vec.used.2, i32 5, i32 1
%vec.used.4 = insertelement <4 x i32> %vec.used.3, i32 5, i32 2
%vec.used.5 = insertelement <4 x i32> %vec.used.4, i32 5, i32 3
%used.here = extractelement <4 x i32> %vec.used.4, i32 3
; vector is not completely overwritten in the loop
; CHECK: [[VEC_NOTLOOP_2:%.*]] = insertelement <4 x i32> [[VEC_NOTLOOP_1]], i32 5, i32 0
; CHECK-NEXT: [[VEC_NOTLOOP_3:%.*]] = insertelement <4 x i32> [[VEC_NOTLOOP_2]], i32 5, i32 1
; CHECK-NEXT: [[VEC_NOTLOOP_4:%.*]] = insertelement <4 x i32> [[VEC_NOTLOOP_3]], i32 5, i32 2
%vec.notloop.2 = insertelement <4 x i32> %vec.notloop.1, i32 5, i32 0
%vec.notloop.3 = insertelement <4 x i32> %vec.notloop.2, i32 5, i32 1
%vec.notloop.4 = insertelement <4 x i32> %vec.notloop.3, i32 5, i32 2
; single use is not insertelement
; CHECK: [[VEC_NOTINSERT_2:%.*]] = insertelement <4 x i32> [[VEC_NOTINSERT_1]], i32 5, i32 0
; CHECK-NEXT: [[VEC_NOTINSERT_3:%.*]] = insertelement <4 x i32> [[VEC_NOTINSERT_2]], i32 5, i32 1
; CHECK-NEXT: [[VEC_NOTINSERT_4:%.*]] = insertelement <4 x i32> [[VEC_NOTINSERT_3]], i32 5, i32 2
; CHECK-NEXT: %notinsert.5 = extractelement <4 x i32> [[VEC_NOTINSERT_4]], i32 3
%vec.notinsert.2 = insertelement <4 x i32> %vec.notinsert.1, i32 5, i32 0
%vec.notinsert.3 = insertelement <4 x i32> %vec.notinsert.2, i32 5, i32 1
%vec.notinsert.4 = insertelement <4 x i32> %vec.notinsert.3, i32 5, i32 2
%notinsert.5 = extractelement <4 x i32> %vec.notinsert.4, i32 3
; scalar
; CHECK: [[INC:%.*]] = add i32 [[SCALAR]], 1
%inc = add i32 %scalar, 1
br i1 true, label %header, label %exit
exit: ; preds = %header
; CHECK: [[VEC_NOTLOOP_5:%.*]] = insertelement <4 x i32> [[VEC_NOTLOOP_4]], i32 5, i32 3
%vec.notloop.5 = insertelement <4 x i32> %vec.notloop.4, i32 5, i32 3
ret void
}
!igc.functions = !{}
|