1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=vector-combine -S %s | FileCheck %s
4 target triple = "arm64-apple-darwin"
6 define void @load_extract_insert_store_const_idx(ptr %A) {
7 ; CHECK-LABEL: @load_extract_insert_store_const_idx(
9 ; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds <225 x double>, ptr [[A:%.*]], i32 0, i64 0
10 ; CHECK-NEXT: [[EXT_0:%.*]] = load double, ptr [[TMP0]], align 8
11 ; CHECK-NEXT: [[MUL:%.*]] = fmul double 2.000000e+01, [[EXT_0]]
12 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds <225 x double>, ptr [[A]], i32 0, i64 1
13 ; CHECK-NEXT: [[EXT_1:%.*]] = load double, ptr [[TMP1]], align 8
14 ; CHECK-NEXT: [[SUB:%.*]] = fsub double [[EXT_1]], [[MUL]]
15 ; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds <225 x double>, ptr [[A]], i64 0, i64 1
16 ; CHECK-NEXT: store double [[SUB]], ptr [[TMP2]], align 8
17 ; CHECK-NEXT: ret void
20 %lv = load <225 x double>, ptr %A, align 8
21 %ext.0 = extractelement <225 x double> %lv, i64 0
22 %mul = fmul double 20.0, %ext.0
23 %ext.1 = extractelement <225 x double> %lv, i64 1
24 %sub = fsub double %ext.1, %mul
25 %ins = insertelement <225 x double> %lv, double %sub, i64 1
26 store <225 x double> %ins, ptr %A, align 8
30 define void @load_extract_insert_store_var_idx_assume_valid(i64 %idx.1, i64 %idx.2, ptr %A) {
31 ; CHECK-LABEL: @load_extract_insert_store_var_idx_assume_valid(
33 ; CHECK-NEXT: [[CMP_1:%.*]] = icmp ult i64 [[IDX_1:%.*]], 225
34 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_1]])
35 ; CHECK-NEXT: [[CMP_2:%.*]] = icmp ult i64 [[IDX_2:%.*]], 225
36 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_2]])
37 ; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds <225 x double>, ptr [[A:%.*]], i32 0, i64 [[IDX_1]]
38 ; CHECK-NEXT: [[EXT_0:%.*]] = load double, ptr [[TMP0]], align 8
39 ; CHECK-NEXT: [[MUL:%.*]] = fmul double 2.000000e+01, [[EXT_0]]
40 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds <225 x double>, ptr [[A]], i32 0, i64 [[IDX_2]]
41 ; CHECK-NEXT: [[EXT_1:%.*]] = load double, ptr [[TMP1]], align 8
42 ; CHECK-NEXT: [[SUB:%.*]] = fsub double [[EXT_1]], [[MUL]]
43 ; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds <225 x double>, ptr [[A]], i64 0, i64 [[IDX_1]]
44 ; CHECK-NEXT: store double [[SUB]], ptr [[TMP2]], align 8
45 ; CHECK-NEXT: ret void
48 %cmp.1 = icmp ult i64 %idx.1, 225
49 call void @llvm.assume(i1 %cmp.1)
50 %cmp.2 = icmp ult i64 %idx.2, 225
51 call void @llvm.assume(i1 %cmp.2)
53 %lv = load <225 x double>, ptr %A, align 8
54 %ext.0 = extractelement <225 x double> %lv, i64 %idx.1
55 %mul = fmul double 20.0, %ext.0
56 %ext.1 = extractelement <225 x double> %lv, i64 %idx.2
57 %sub = fsub double %ext.1, %mul
58 %ins = insertelement <225 x double> %lv, double %sub, i64 %idx.1
59 store <225 x double> %ins, ptr %A, align 8
65 define void @load_extract_insert_store_var_idx_assume_valid_in_dominating_block(i64 %idx.1, i64 %idx.2, ptr %A, i1 %c.1) {
66 ; CHECK-LABEL: @load_extract_insert_store_var_idx_assume_valid_in_dominating_block(
68 ; CHECK-NEXT: [[CMP_1:%.*]] = icmp ult i64 [[IDX_1:%.*]], 225
69 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_1]])
70 ; CHECK-NEXT: [[CMP_2:%.*]] = icmp ult i64 [[IDX_2:%.*]], 225
71 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_2]])
72 ; CHECK-NEXT: br i1 [[C_1:%.*]], label [[LOOP:%.*]], label [[EXIT:%.*]]
74 ; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds <225 x double>, ptr [[A:%.*]], i32 0, i64 [[IDX_1]]
75 ; CHECK-NEXT: [[EXT_0:%.*]] = load double, ptr [[TMP0]], align 8
76 ; CHECK-NEXT: [[MUL:%.*]] = fmul double 2.000000e+01, [[EXT_0]]
77 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds <225 x double>, ptr [[A]], i32 0, i64 [[IDX_2]]
78 ; CHECK-NEXT: [[EXT_1:%.*]] = load double, ptr [[TMP1]], align 8
79 ; CHECK-NEXT: [[SUB:%.*]] = fsub double [[EXT_1]], [[MUL]]
80 ; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds <225 x double>, ptr [[A]], i64 0, i64 [[IDX_1]]
81 ; CHECK-NEXT: store double [[SUB]], ptr [[TMP2]], align 8
82 ; CHECK-NEXT: [[C_2:%.*]] = call i1 @cond()
83 ; CHECK-NEXT: br i1 [[C_2]], label [[LOOP]], label [[EXIT]]
85 ; CHECK-NEXT: ret void
88 %cmp.1 = icmp ult i64 %idx.1, 225
89 call void @llvm.assume(i1 %cmp.1)
90 %cmp.2 = icmp ult i64 %idx.2, 225
91 call void @llvm.assume(i1 %cmp.2)
92 br i1 %c.1, label %loop, label %exit
95 %lv = load <225 x double>, ptr %A, align 8
96 %ext.0 = extractelement <225 x double> %lv, i64 %idx.1
97 %mul = fmul double 20.0, %ext.0
98 %ext.1 = extractelement <225 x double> %lv, i64 %idx.2
99 %sub = fsub double %ext.1, %mul
100 %ins = insertelement <225 x double> %lv, double %sub, i64 %idx.1
101 store <225 x double> %ins, ptr %A, align 8
102 %c.2 = call i1 @cond()
103 br i1 %c.2, label %loop, label %exit
109 define void @load_extract_insert_store_var_idx_assume_valid_in_non_dominating_block(i64 %idx.1, i64 %idx.2, ptr %A, i1 %c.1, i1 %c.2) {
110 ; CHECK-LABEL: @load_extract_insert_store_var_idx_assume_valid_in_non_dominating_block(
112 ; CHECK-NEXT: br i1 [[C_1:%.*]], label [[ASSUME_BLOCK:%.*]], label [[LOOP:%.*]]
113 ; CHECK: assume_block:
114 ; CHECK-NEXT: [[CMP_1:%.*]] = icmp ult i64 [[IDX_1:%.*]], 225
115 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_1]])
116 ; CHECK-NEXT: [[CMP_2:%.*]] = icmp ult i64 [[IDX_2:%.*]], 225
117 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_2]])
118 ; CHECK-NEXT: br i1 [[C_2:%.*]], label [[LOOP]], label [[EXIT:%.*]]
120 ; CHECK-NEXT: [[LV:%.*]] = load <225 x double>, ptr [[A:%.*]], align 8
121 ; CHECK-NEXT: [[EXT_0:%.*]] = extractelement <225 x double> [[LV]], i64 [[IDX_1]]
122 ; CHECK-NEXT: [[MUL:%.*]] = fmul double 2.000000e+01, [[EXT_0]]
123 ; CHECK-NEXT: [[EXT_1:%.*]] = extractelement <225 x double> [[LV]], i64 [[IDX_2]]
124 ; CHECK-NEXT: [[SUB:%.*]] = fsub double [[EXT_1]], [[MUL]]
125 ; CHECK-NEXT: [[INS:%.*]] = insertelement <225 x double> [[LV]], double [[SUB]], i64 [[IDX_1]]
126 ; CHECK-NEXT: store <225 x double> [[INS]], ptr [[A]], align 8
127 ; CHECK-NEXT: [[C_3:%.*]] = call i1 @cond()
128 ; CHECK-NEXT: br i1 [[C_3]], label [[LOOP]], label [[EXIT]]
130 ; CHECK-NEXT: ret void
133 br i1 %c.1, label %assume_block, label %loop
136 %cmp.1 = icmp ult i64 %idx.1, 225
137 call void @llvm.assume(i1 %cmp.1)
138 %cmp.2 = icmp ult i64 %idx.2, 225
139 call void @llvm.assume(i1 %cmp.2)
140 br i1 %c.2, label %loop, label %exit
143 %lv = load <225 x double>, ptr %A, align 8
144 %ext.0 = extractelement <225 x double> %lv, i64 %idx.1
145 %mul = fmul double 20.0, %ext.0
146 %ext.1 = extractelement <225 x double> %lv, i64 %idx.2
147 %sub = fsub double %ext.1, %mul
148 %ins = insertelement <225 x double> %lv, double %sub, i64 %idx.1
149 store <225 x double> %ins, ptr %A, align 8
150 %c.3 = call i1 @cond()
151 br i1 %c.3, label %loop, label %exit
157 define void @load_extract_insert_store_var_idx_no_assume_valid(i64 %idx.1, i64 %idx.2, ptr %A) {
158 ; CHECK-LABEL: @load_extract_insert_store_var_idx_no_assume_valid(
160 ; CHECK-NEXT: [[LV:%.*]] = load <225 x double>, ptr [[A:%.*]], align 8
161 ; CHECK-NEXT: [[EXT_0:%.*]] = extractelement <225 x double> [[LV]], i64 [[IDX_1:%.*]]
162 ; CHECK-NEXT: [[MUL:%.*]] = fmul double 2.000000e+01, [[EXT_0]]
163 ; CHECK-NEXT: [[EXT_1:%.*]] = extractelement <225 x double> [[LV]], i64 [[IDX_2:%.*]]
164 ; CHECK-NEXT: [[SUB:%.*]] = fsub double [[EXT_1]], [[MUL]]
165 ; CHECK-NEXT: [[INS:%.*]] = insertelement <225 x double> [[LV]], double [[SUB]], i64 [[IDX_1]]
166 ; CHECK-NEXT: store <225 x double> [[INS]], ptr [[A]], align 8
167 ; CHECK-NEXT: ret void
170 %lv = load <225 x double>, ptr %A, align 8
171 %ext.0 = extractelement <225 x double> %lv, i64 %idx.1
172 %mul = fmul double 20.0, %ext.0
173 %ext.1 = extractelement <225 x double> %lv, i64 %idx.2
174 %sub = fsub double %ext.1, %mul
175 %ins = insertelement <225 x double> %lv, double %sub, i64 %idx.1
176 store <225 x double> %ins, ptr %A, align 8
180 declare void @llvm.assume(i1)