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 139 140 141 142 143 144 145 146 147 148 149 150 151
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -S < %s -load-store-vectorizer | FileCheck %s
; RUN: opt -S < %s -passes='function(load-store-vectorizer)' | FileCheck %s
declare void @llvm.sideeffect()
; load-store vectorization across a @llvm.sideeffect.
define void @test_sideeffect(float* %p) {
; CHECK-LABEL: @test_sideeffect(
; CHECK-NEXT: [[P0:%.*]] = getelementptr float, float* [[P:%.*]], i64 0
; CHECK-NEXT: [[TMP1:%.*]] = bitcast float* [[P0]] to <4 x float>*
; CHECK-NEXT: [[TMP2:%.*]] = load <4 x float>, <4 x float>* [[TMP1]], align 16
; CHECK-NEXT: [[L01:%.*]] = extractelement <4 x float> [[TMP2]], i32 0
; CHECK-NEXT: [[L12:%.*]] = extractelement <4 x float> [[TMP2]], i32 1
; CHECK-NEXT: [[L23:%.*]] = extractelement <4 x float> [[TMP2]], i32 2
; CHECK-NEXT: [[L34:%.*]] = extractelement <4 x float> [[TMP2]], i32 3
; CHECK-NEXT: call void @llvm.sideeffect()
; CHECK-NEXT: call void @llvm.sideeffect()
; CHECK-NEXT: [[TMP3:%.*]] = insertelement <4 x float> poison, float [[L01]], i32 0
; CHECK-NEXT: [[TMP4:%.*]] = insertelement <4 x float> [[TMP3]], float [[L12]], i32 1
; CHECK-NEXT: [[TMP5:%.*]] = insertelement <4 x float> [[TMP4]], float [[L23]], i32 2
; CHECK-NEXT: [[TMP6:%.*]] = insertelement <4 x float> [[TMP5]], float [[L34]], i32 3
; CHECK-NEXT: [[TMP7:%.*]] = bitcast float* [[P0]] to <4 x float>*
; CHECK-NEXT: store <4 x float> [[TMP6]], <4 x float>* [[TMP7]], align 16
; CHECK-NEXT: ret void
;
%p0 = getelementptr float, float* %p, i64 0
%p1 = getelementptr float, float* %p, i64 1
%p2 = getelementptr float, float* %p, i64 2
%p3 = getelementptr float, float* %p, i64 3
%l0 = load float, float* %p0, align 16
%l1 = load float, float* %p1
%l2 = load float, float* %p2
call void @llvm.sideeffect()
%l3 = load float, float* %p3
store float %l0, float* %p0, align 16
call void @llvm.sideeffect()
store float %l1, float* %p1
store float %l2, float* %p2
store float %l3, float* %p3
ret void
}
declare void @foo()
define void @test_inaccessiblememonly_nounwind_willreturn(float* %p) {
; CHECK-LABEL: @test_inaccessiblememonly_nounwind_willreturn(
; CHECK-NEXT: [[P0:%.*]] = getelementptr float, float* [[P:%.*]], i64 0
; CHECK-NEXT: [[TMP1:%.*]] = bitcast float* [[P0]] to <4 x float>*
; CHECK-NEXT: [[TMP2:%.*]] = load <4 x float>, <4 x float>* [[TMP1]], align 16
; CHECK-NEXT: [[L01:%.*]] = extractelement <4 x float> [[TMP2]], i32 0
; CHECK-NEXT: [[L12:%.*]] = extractelement <4 x float> [[TMP2]], i32 1
; CHECK-NEXT: [[L23:%.*]] = extractelement <4 x float> [[TMP2]], i32 2
; CHECK-NEXT: [[L34:%.*]] = extractelement <4 x float> [[TMP2]], i32 3
; CHECK-NEXT: call void @foo() #[[ATTR1:[0-9]+]]
; CHECK-NEXT: call void @foo() #[[ATTR1]]
; CHECK-NEXT: [[TMP3:%.*]] = insertelement <4 x float> poison, float [[L01]], i32 0
; CHECK-NEXT: [[TMP4:%.*]] = insertelement <4 x float> [[TMP3]], float [[L12]], i32 1
; CHECK-NEXT: [[TMP5:%.*]] = insertelement <4 x float> [[TMP4]], float [[L23]], i32 2
; CHECK-NEXT: [[TMP6:%.*]] = insertelement <4 x float> [[TMP5]], float [[L34]], i32 3
; CHECK-NEXT: [[TMP7:%.*]] = bitcast float* [[P0]] to <4 x float>*
; CHECK-NEXT: store <4 x float> [[TMP6]], <4 x float>* [[TMP7]], align 16
; CHECK-NEXT: ret void
;
%p0 = getelementptr float, float* %p, i64 0
%p1 = getelementptr float, float* %p, i64 1
%p2 = getelementptr float, float* %p, i64 2
%p3 = getelementptr float, float* %p, i64 3
%l0 = load float, float* %p0, align 16
%l1 = load float, float* %p1
%l2 = load float, float* %p2
call void @foo() inaccessiblememonly nounwind willreturn
%l3 = load float, float* %p3
store float %l0, float* %p0, align 16
call void @foo() inaccessiblememonly nounwind willreturn
store float %l1, float* %p1
store float %l2, float* %p2
store float %l3, float* %p3
ret void
}
define void @test_inaccessiblememonly_not_willreturn(float* %p) {
; CHECK-LABEL: @test_inaccessiblememonly_not_willreturn(
; CHECK-NEXT: [[P0:%.*]] = getelementptr float, float* [[P:%.*]], i64 0
; CHECK-NEXT: [[P1:%.*]] = getelementptr float, float* [[P]], i64 1
; CHECK-NEXT: [[P2:%.*]] = getelementptr float, float* [[P]], i64 2
; CHECK-NEXT: [[P3:%.*]] = getelementptr float, float* [[P]], i64 3
; CHECK-NEXT: [[L0:%.*]] = load float, float* [[P0]], align 16
; CHECK-NEXT: [[L1:%.*]] = load float, float* [[P1]], align 4
; CHECK-NEXT: [[L2:%.*]] = load float, float* [[P2]], align 4
; CHECK-NEXT: call void @foo() #[[ATTR2:[0-9]+]]
; CHECK-NEXT: [[L3:%.*]] = load float, float* [[P3]], align 4
; CHECK-NEXT: store float [[L0]], float* [[P0]], align 16
; CHECK-NEXT: call void @foo() #[[ATTR2]]
; CHECK-NEXT: store float [[L1]], float* [[P1]], align 4
; CHECK-NEXT: store float [[L2]], float* [[P2]], align 4
; CHECK-NEXT: store float [[L3]], float* [[P3]], align 4
; CHECK-NEXT: ret void
;
%p0 = getelementptr float, float* %p, i64 0
%p1 = getelementptr float, float* %p, i64 1
%p2 = getelementptr float, float* %p, i64 2
%p3 = getelementptr float, float* %p, i64 3
%l0 = load float, float* %p0, align 16
%l1 = load float, float* %p1
%l2 = load float, float* %p2
call void @foo() inaccessiblememonly nounwind
%l3 = load float, float* %p3
store float %l0, float* %p0, align 16
call void @foo() inaccessiblememonly nounwind
store float %l1, float* %p1
store float %l2, float* %p2
store float %l3, float* %p3
ret void
}
define void @test_inaccessiblememonly_not_nounwind(float* %p) {
; CHECK-LABEL: @test_inaccessiblememonly_not_nounwind(
; CHECK-NEXT: [[P0:%.*]] = getelementptr float, float* [[P:%.*]], i64 0
; CHECK-NEXT: [[P1:%.*]] = getelementptr float, float* [[P]], i64 1
; CHECK-NEXT: [[P2:%.*]] = getelementptr float, float* [[P]], i64 2
; CHECK-NEXT: [[P3:%.*]] = getelementptr float, float* [[P]], i64 3
; CHECK-NEXT: [[L0:%.*]] = load float, float* [[P0]], align 16
; CHECK-NEXT: [[L1:%.*]] = load float, float* [[P1]], align 4
; CHECK-NEXT: [[L2:%.*]] = load float, float* [[P2]], align 4
; CHECK-NEXT: call void @foo() #[[ATTR3:[0-9]+]]
; CHECK-NEXT: [[L3:%.*]] = load float, float* [[P3]], align 4
; CHECK-NEXT: store float [[L0]], float* [[P0]], align 16
; CHECK-NEXT: call void @foo() #[[ATTR3]]
; CHECK-NEXT: store float [[L1]], float* [[P1]], align 4
; CHECK-NEXT: store float [[L2]], float* [[P2]], align 4
; CHECK-NEXT: store float [[L3]], float* [[P3]], align 4
; CHECK-NEXT: ret void
;
%p0 = getelementptr float, float* %p, i64 0
%p1 = getelementptr float, float* %p, i64 1
%p2 = getelementptr float, float* %p, i64 2
%p3 = getelementptr float, float* %p, i64 3
%l0 = load float, float* %p0, align 16
%l1 = load float, float* %p1
%l2 = load float, float* %p2
call void @foo() inaccessiblememonly willreturn
%l3 = load float, float* %p3
store float %l0, float* %p0, align 16
call void @foo() inaccessiblememonly willreturn
store float %l1, float* %p1
store float %l2, float* %p2
store float %l3, float* %p3
ret void
}
|