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
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -S < %s -passes=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(ptr %p) {
; CHECK-LABEL: @test_sideeffect(
; CHECK-NEXT: [[TMP2:%.*]] = load <4 x float>, ptr [[P:%.*]], 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: store <4 x float> [[TMP6]], ptr [[P]], align 16
; CHECK-NEXT: ret void
;
%p1 = getelementptr float, ptr %p, i64 1
%p2 = getelementptr float, ptr %p, i64 2
%p3 = getelementptr float, ptr %p, i64 3
%l0 = load float, ptr %p, align 16
%l1 = load float, ptr %p1
%l2 = load float, ptr %p2
call void @llvm.sideeffect()
%l3 = load float, ptr %p3
store float %l0, ptr %p, align 16
call void @llvm.sideeffect()
store float %l1, ptr %p1
store float %l2, ptr %p2
store float %l3, ptr %p3
ret void
}
declare void @foo()
define void @test_inaccessiblememonly_nounwind_willreturn(ptr %p) {
; CHECK-LABEL: @test_inaccessiblememonly_nounwind_willreturn(
; CHECK-NEXT: [[TMP2:%.*]] = load <4 x float>, ptr [[P:%.*]], 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: store <4 x float> [[TMP6]], ptr [[P]], align 16
; CHECK-NEXT: ret void
;
%p1 = getelementptr float, ptr %p, i64 1
%p2 = getelementptr float, ptr %p, i64 2
%p3 = getelementptr float, ptr %p, i64 3
%l0 = load float, ptr %p, align 16
%l1 = load float, ptr %p1
%l2 = load float, ptr %p2
call void @foo() inaccessiblememonly nounwind willreturn
%l3 = load float, ptr %p3
store float %l0, ptr %p, align 16
call void @foo() inaccessiblememonly nounwind willreturn
store float %l1, ptr %p1
store float %l2, ptr %p2
store float %l3, ptr %p3
ret void
}
define void @test_inaccessiblememonly_not_willreturn(ptr %p) {
; CHECK-LABEL: @test_inaccessiblememonly_not_willreturn(
; CHECK-NEXT: [[P1:%.*]] = getelementptr float, ptr [[P:%.*]], i64 1
; CHECK-NEXT: [[P2:%.*]] = getelementptr float, ptr [[P]], i64 2
; CHECK-NEXT: [[P3:%.*]] = getelementptr float, ptr [[P]], i64 3
; CHECK-NEXT: [[L0:%.*]] = load float, ptr [[P]], align 16
; CHECK-NEXT: call void @foo() #[[ATTR2:[0-9]+]]
; CHECK-NEXT: [[L1:%.*]] = load float, ptr [[P1]], align 4
; CHECK-NEXT: [[L2:%.*]] = load float, ptr [[P2]], align 4
; CHECK-NEXT: [[L3:%.*]] = load float, ptr [[P3]], align 4
; CHECK-NEXT: store float [[L0]], ptr [[P]], align 16
; CHECK-NEXT: call void @foo() #[[ATTR2]]
; CHECK-NEXT: store float [[L1]], ptr [[P1]], align 4
; CHECK-NEXT: store float [[L2]], ptr [[P2]], align 4
; CHECK-NEXT: store float [[L3]], ptr [[P3]], align 4
; CHECK-NEXT: ret void
;
%p1 = getelementptr float, ptr %p, i64 1
%p2 = getelementptr float, ptr %p, i64 2
%p3 = getelementptr float, ptr %p, i64 3
%l0 = load float, ptr %p, align 16
call void @foo() inaccessiblememonly nounwind
%l1 = load float, ptr %p1
%l2 = load float, ptr %p2
%l3 = load float, ptr %p3
store float %l0, ptr %p, align 16
call void @foo() inaccessiblememonly nounwind
store float %l1, ptr %p1
store float %l2, ptr %p2
store float %l3, ptr %p3
ret void
}
define void @test_inaccessiblememonly_not_nounwind(ptr %p) {
; CHECK-LABEL: @test_inaccessiblememonly_not_nounwind(
; CHECK-NEXT: [[P1:%.*]] = getelementptr float, ptr [[P:%.*]], i64 1
; CHECK-NEXT: [[P2:%.*]] = getelementptr float, ptr [[P]], i64 2
; CHECK-NEXT: [[P3:%.*]] = getelementptr float, ptr [[P]], i64 3
; CHECK-NEXT: [[L0:%.*]] = load float, ptr [[P]], align 16
; CHECK-NEXT: call void @foo() #[[ATTR3:[0-9]+]]
; CHECK-NEXT: [[L1:%.*]] = load float, ptr [[P1]], align 4
; CHECK-NEXT: [[L2:%.*]] = load float, ptr [[P2]], align 4
; CHECK-NEXT: [[L3:%.*]] = load float, ptr [[P3]], align 4
; CHECK-NEXT: store float [[L0]], ptr [[P]], align 16
; CHECK-NEXT: call void @foo() #[[ATTR3]]
; CHECK-NEXT: store float [[L1]], ptr [[P1]], align 4
; CHECK-NEXT: store float [[L2]], ptr [[P2]], align 4
; CHECK-NEXT: store float [[L3]], ptr [[P3]], align 4
; CHECK-NEXT: ret void
;
%p1 = getelementptr float, ptr %p, i64 1
%p2 = getelementptr float, ptr %p, i64 2
%p3 = getelementptr float, ptr %p, i64 3
%l0 = load float, ptr %p, align 16
call void @foo() inaccessiblememonly willreturn
%l1 = load float, ptr %p1
%l2 = load float, ptr %p2
%l3 = load float, ptr %p3
store float %l0, ptr %p, align 16
call void @foo() inaccessiblememonly willreturn
store float %l1, ptr %p1
store float %l2, ptr %p2
store float %l3, ptr %p3
ret void
}
|