[LLVMdev] SLP vectorizer on AVX feature

Frank Winter fwinter at jlab.org
Wed Jul 1 07:51:31 PDT 2015


I seem to have problem to get the SLP vectorizer to make use of the full 
8 floats available in a SIMD vector on a Sandy Bridge CPU with AVX. The 
function is attached, the CPU flags are:

flags        : fpu vme de pse tsc msr pae mce cx8 apic mtrr pge mca cmov 
pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx 
pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good xtopology 
nonstop_tsc aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est 
tm2 ssse3 cx16 xtpr pdcm dca sse4_1 sse4_2 x2apic popcnt aes xsave avx 
lahf_lm ida arat epb xsaveopt pln pts dts tpr_shadow vnmi flexpriority 
ept vpid

I use LLVM 3.6 checked out yesterday

~/toolchain/install/llvm-3.6/bin/opt -datalayout -basicaa 
-slp-vectorizer -instcombine < func_4x4x4_scalar_p_scalar.ll -S

the output goes like:

; ModuleID = '<stdin>'

define void @main(i64 %lo, i64 %hi, float* noalias %arg0, float* noalias 
%arg1, float* noalias %arg2) {
entrypoint:
   %0 = bitcast float* %arg1 to <4 x float>*
   %1 = load <4 x float>* %0, align 4
   %2 = bitcast float* %arg2 to <4 x float>*
   %3 = load <4 x float>* %2, align 4
   %4 = fadd <4 x float> %3, %1
   %5 = bitcast float* %arg0 to <4 x float>*
   store <4 x float> %4, <4 x float>* %5, align 4
....

So, it could make use of <8 x float> available in that machine. But it 
doesn't. Then I thought, that maybe the YMM registers get used when 
lowering the IR to machine code. However, the generated assembly doesn't 
seem to support this assumption :-(


main:
     .cfi_startproc
     xorl    %eax, %eax
     xorl    %esi, %esi
     .align    16, 0x90
.LBB0_1:
     vmovups    (%r8,%rax), %xmm0
     vaddps    (%rcx,%rax), %xmm0, %xmm0
     vmovups    %xmm0, (%rdx,%rax)
     addq    $4, %rsi
     addq    $16, %rax
     cmpq    $61, %rsi
     jb    .LBB0_1
     retq

I played with -mcpu and -march switches without success. In any case, 
the target architecture should be detected with the -datalayout pass, right?

Any idea what I am missing?

Frank

-------------- next part --------------
define void @main(i64 %lo, i64 %hi, float* noalias %arg0, float* noalias %arg1, float* noalias %arg2) {
entrypoint:
  %0 = getelementptr float* %arg1, i32 0
  %1 = load float* %0
  %2 = getelementptr float* %arg2, i32 0
  %3 = load float* %2
  %4 = fadd float %3, %1
  %5 = getelementptr float* %arg0, i32 0
  store float %4, float* %5
  %6 = getelementptr float* %arg1, i32 1
  %7 = load float* %6
  %8 = getelementptr float* %arg2, i32 1
  %9 = load float* %8
  %10 = fadd float %9, %7
  %11 = getelementptr float* %arg0, i32 1
  store float %10, float* %11
  %12 = getelementptr float* %arg1, i32 2
  %13 = load float* %12
  %14 = getelementptr float* %arg2, i32 2
  %15 = load float* %14
  %16 = fadd float %15, %13
  %17 = getelementptr float* %arg0, i32 2
  store float %16, float* %17
  %18 = getelementptr float* %arg1, i32 3
  %19 = load float* %18
  %20 = getelementptr float* %arg2, i32 3
  %21 = load float* %20
  %22 = fadd float %21, %19
  %23 = getelementptr float* %arg0, i32 3
  store float %22, float* %23
  %24 = getelementptr float* %arg1, i32 4
  %25 = load float* %24
  %26 = getelementptr float* %arg2, i32 4
  %27 = load float* %26
  %28 = fadd float %27, %25
  %29 = getelementptr float* %arg0, i32 4
  store float %28, float* %29
  %30 = getelementptr float* %arg1, i32 5
  %31 = load float* %30
  %32 = getelementptr float* %arg2, i32 5
  %33 = load float* %32
  %34 = fadd float %33, %31
  %35 = getelementptr float* %arg0, i32 5
  store float %34, float* %35
  %36 = getelementptr float* %arg1, i32 6
  %37 = load float* %36
  %38 = getelementptr float* %arg2, i32 6
  %39 = load float* %38
  %40 = fadd float %39, %37
  %41 = getelementptr float* %arg0, i32 6
  store float %40, float* %41
  %42 = getelementptr float* %arg1, i32 7
  %43 = load float* %42
  %44 = getelementptr float* %arg2, i32 7
  %45 = load float* %44
  %46 = fadd float %45, %43
  %47 = getelementptr float* %arg0, i32 7
  store float %46, float* %47
  %48 = getelementptr float* %arg1, i32 8
  %49 = load float* %48
  %50 = getelementptr float* %arg2, i32 8
  %51 = load float* %50
  %52 = fadd float %51, %49
  %53 = getelementptr float* %arg0, i32 8
  store float %52, float* %53
  %54 = getelementptr float* %arg1, i32 9
  %55 = load float* %54
  %56 = getelementptr float* %arg2, i32 9
  %57 = load float* %56
  %58 = fadd float %57, %55
  %59 = getelementptr float* %arg0, i32 9
  store float %58, float* %59
  %60 = getelementptr float* %arg1, i32 10
  %61 = load float* %60
  %62 = getelementptr float* %arg2, i32 10
  %63 = load float* %62
  %64 = fadd float %63, %61
  %65 = getelementptr float* %arg0, i32 10
  store float %64, float* %65
  %66 = getelementptr float* %arg1, i32 11
  %67 = load float* %66
  %68 = getelementptr float* %arg2, i32 11
  %69 = load float* %68
  %70 = fadd float %69, %67
  %71 = getelementptr float* %arg0, i32 11
  store float %70, float* %71
  %72 = getelementptr float* %arg1, i32 12
  %73 = load float* %72
  %74 = getelementptr float* %arg2, i32 12
  %75 = load float* %74
  %76 = fadd float %75, %73
  %77 = getelementptr float* %arg0, i32 12
  store float %76, float* %77
  %78 = getelementptr float* %arg1, i32 13
  %79 = load float* %78
  %80 = getelementptr float* %arg2, i32 13
  %81 = load float* %80
  %82 = fadd float %81, %79
  %83 = getelementptr float* %arg0, i32 13
  store float %82, float* %83
  %84 = getelementptr float* %arg1, i32 14
  %85 = load float* %84
  %86 = getelementptr float* %arg2, i32 14
  %87 = load float* %86
  %88 = fadd float %87, %85
  %89 = getelementptr float* %arg0, i32 14
  store float %88, float* %89
  %90 = getelementptr float* %arg1, i32 15
  %91 = load float* %90
  %92 = getelementptr float* %arg2, i32 15
  %93 = load float* %92
  %94 = fadd float %93, %91
  %95 = getelementptr float* %arg0, i32 15
  store float %94, float* %95
  %96 = getelementptr float* %arg1, i32 16
  %97 = load float* %96
  %98 = getelementptr float* %arg2, i32 16
  %99 = load float* %98
  %100 = fadd float %99, %97
  %101 = getelementptr float* %arg0, i32 16
  store float %100, float* %101
  %102 = getelementptr float* %arg1, i32 17
  %103 = load float* %102
  %104 = getelementptr float* %arg2, i32 17
  %105 = load float* %104
  %106 = fadd float %105, %103
  %107 = getelementptr float* %arg0, i32 17
  store float %106, float* %107
  %108 = getelementptr float* %arg1, i32 18
  %109 = load float* %108
  %110 = getelementptr float* %arg2, i32 18
  %111 = load float* %110
  %112 = fadd float %111, %109
  %113 = getelementptr float* %arg0, i32 18
  store float %112, float* %113
  %114 = getelementptr float* %arg1, i32 19
  %115 = load float* %114
  %116 = getelementptr float* %arg2, i32 19
  %117 = load float* %116
  %118 = fadd float %117, %115
  %119 = getelementptr float* %arg0, i32 19
  store float %118, float* %119
  %120 = getelementptr float* %arg1, i32 20
  %121 = load float* %120
  %122 = getelementptr float* %arg2, i32 20
  %123 = load float* %122
  %124 = fadd float %123, %121
  %125 = getelementptr float* %arg0, i32 20
  store float %124, float* %125
  %126 = getelementptr float* %arg1, i32 21
  %127 = load float* %126
  %128 = getelementptr float* %arg2, i32 21
  %129 = load float* %128
  %130 = fadd float %129, %127
  %131 = getelementptr float* %arg0, i32 21
  store float %130, float* %131
  %132 = getelementptr float* %arg1, i32 22
  %133 = load float* %132
  %134 = getelementptr float* %arg2, i32 22
  %135 = load float* %134
  %136 = fadd float %135, %133
  %137 = getelementptr float* %arg0, i32 22
  store float %136, float* %137
  %138 = getelementptr float* %arg1, i32 23
  %139 = load float* %138
  %140 = getelementptr float* %arg2, i32 23
  %141 = load float* %140
  %142 = fadd float %141, %139
  %143 = getelementptr float* %arg0, i32 23
  store float %142, float* %143
  %144 = getelementptr float* %arg1, i32 24
  %145 = load float* %144
  %146 = getelementptr float* %arg2, i32 24
  %147 = load float* %146
  %148 = fadd float %147, %145
  %149 = getelementptr float* %arg0, i32 24
  store float %148, float* %149
  %150 = getelementptr float* %arg1, i32 25
  %151 = load float* %150
  %152 = getelementptr float* %arg2, i32 25
  %153 = load float* %152
  %154 = fadd float %153, %151
  %155 = getelementptr float* %arg0, i32 25
  store float %154, float* %155
  %156 = getelementptr float* %arg1, i32 26
  %157 = load float* %156
  %158 = getelementptr float* %arg2, i32 26
  %159 = load float* %158
  %160 = fadd float %159, %157
  %161 = getelementptr float* %arg0, i32 26
  store float %160, float* %161
  %162 = getelementptr float* %arg1, i32 27
  %163 = load float* %162
  %164 = getelementptr float* %arg2, i32 27
  %165 = load float* %164
  %166 = fadd float %165, %163
  %167 = getelementptr float* %arg0, i32 27
  store float %166, float* %167
  %168 = getelementptr float* %arg1, i32 28
  %169 = load float* %168
  %170 = getelementptr float* %arg2, i32 28
  %171 = load float* %170
  %172 = fadd float %171, %169
  %173 = getelementptr float* %arg0, i32 28
  store float %172, float* %173
  %174 = getelementptr float* %arg1, i32 29
  %175 = load float* %174
  %176 = getelementptr float* %arg2, i32 29
  %177 = load float* %176
  %178 = fadd float %177, %175
  %179 = getelementptr float* %arg0, i32 29
  store float %178, float* %179
  %180 = getelementptr float* %arg1, i32 30
  %181 = load float* %180
  %182 = getelementptr float* %arg2, i32 30
  %183 = load float* %182
  %184 = fadd float %183, %181
  %185 = getelementptr float* %arg0, i32 30
  store float %184, float* %185
  %186 = getelementptr float* %arg1, i32 31
  %187 = load float* %186
  %188 = getelementptr float* %arg2, i32 31
  %189 = load float* %188
  %190 = fadd float %189, %187
  %191 = getelementptr float* %arg0, i32 31
  store float %190, float* %191
  %192 = getelementptr float* %arg1, i32 32
  %193 = load float* %192
  %194 = getelementptr float* %arg2, i32 32
  %195 = load float* %194
  %196 = fadd float %195, %193
  %197 = getelementptr float* %arg0, i32 32
  store float %196, float* %197
  %198 = getelementptr float* %arg1, i32 33
  %199 = load float* %198
  %200 = getelementptr float* %arg2, i32 33
  %201 = load float* %200
  %202 = fadd float %201, %199
  %203 = getelementptr float* %arg0, i32 33
  store float %202, float* %203
  %204 = getelementptr float* %arg1, i32 34
  %205 = load float* %204
  %206 = getelementptr float* %arg2, i32 34
  %207 = load float* %206
  %208 = fadd float %207, %205
  %209 = getelementptr float* %arg0, i32 34
  store float %208, float* %209
  %210 = getelementptr float* %arg1, i32 35
  %211 = load float* %210
  %212 = getelementptr float* %arg2, i32 35
  %213 = load float* %212
  %214 = fadd float %213, %211
  %215 = getelementptr float* %arg0, i32 35
  store float %214, float* %215
  %216 = getelementptr float* %arg1, i32 36
  %217 = load float* %216
  %218 = getelementptr float* %arg2, i32 36
  %219 = load float* %218
  %220 = fadd float %219, %217
  %221 = getelementptr float* %arg0, i32 36
  store float %220, float* %221
  %222 = getelementptr float* %arg1, i32 37
  %223 = load float* %222
  %224 = getelementptr float* %arg2, i32 37
  %225 = load float* %224
  %226 = fadd float %225, %223
  %227 = getelementptr float* %arg0, i32 37
  store float %226, float* %227
  %228 = getelementptr float* %arg1, i32 38
  %229 = load float* %228
  %230 = getelementptr float* %arg2, i32 38
  %231 = load float* %230
  %232 = fadd float %231, %229
  %233 = getelementptr float* %arg0, i32 38
  store float %232, float* %233
  %234 = getelementptr float* %arg1, i32 39
  %235 = load float* %234
  %236 = getelementptr float* %arg2, i32 39
  %237 = load float* %236
  %238 = fadd float %237, %235
  %239 = getelementptr float* %arg0, i32 39
  store float %238, float* %239
  %240 = getelementptr float* %arg1, i32 40
  %241 = load float* %240
  %242 = getelementptr float* %arg2, i32 40
  %243 = load float* %242
  %244 = fadd float %243, %241
  %245 = getelementptr float* %arg0, i32 40
  store float %244, float* %245
  %246 = getelementptr float* %arg1, i32 41
  %247 = load float* %246
  %248 = getelementptr float* %arg2, i32 41
  %249 = load float* %248
  %250 = fadd float %249, %247
  %251 = getelementptr float* %arg0, i32 41
  store float %250, float* %251
  %252 = getelementptr float* %arg1, i32 42
  %253 = load float* %252
  %254 = getelementptr float* %arg2, i32 42
  %255 = load float* %254
  %256 = fadd float %255, %253
  %257 = getelementptr float* %arg0, i32 42
  store float %256, float* %257
  %258 = getelementptr float* %arg1, i32 43
  %259 = load float* %258
  %260 = getelementptr float* %arg2, i32 43
  %261 = load float* %260
  %262 = fadd float %261, %259
  %263 = getelementptr float* %arg0, i32 43
  store float %262, float* %263
  %264 = getelementptr float* %arg1, i32 44
  %265 = load float* %264
  %266 = getelementptr float* %arg2, i32 44
  %267 = load float* %266
  %268 = fadd float %267, %265
  %269 = getelementptr float* %arg0, i32 44
  store float %268, float* %269
  %270 = getelementptr float* %arg1, i32 45
  %271 = load float* %270
  %272 = getelementptr float* %arg2, i32 45
  %273 = load float* %272
  %274 = fadd float %273, %271
  %275 = getelementptr float* %arg0, i32 45
  store float %274, float* %275
  %276 = getelementptr float* %arg1, i32 46
  %277 = load float* %276
  %278 = getelementptr float* %arg2, i32 46
  %279 = load float* %278
  %280 = fadd float %279, %277
  %281 = getelementptr float* %arg0, i32 46
  store float %280, float* %281
  %282 = getelementptr float* %arg1, i32 47
  %283 = load float* %282
  %284 = getelementptr float* %arg2, i32 47
  %285 = load float* %284
  %286 = fadd float %285, %283
  %287 = getelementptr float* %arg0, i32 47
  store float %286, float* %287
  %288 = getelementptr float* %arg1, i32 48
  %289 = load float* %288
  %290 = getelementptr float* %arg2, i32 48
  %291 = load float* %290
  %292 = fadd float %291, %289
  %293 = getelementptr float* %arg0, i32 48
  store float %292, float* %293
  %294 = getelementptr float* %arg1, i32 49
  %295 = load float* %294
  %296 = getelementptr float* %arg2, i32 49
  %297 = load float* %296
  %298 = fadd float %297, %295
  %299 = getelementptr float* %arg0, i32 49
  store float %298, float* %299
  %300 = getelementptr float* %arg1, i32 50
  %301 = load float* %300
  %302 = getelementptr float* %arg2, i32 50
  %303 = load float* %302
  %304 = fadd float %303, %301
  %305 = getelementptr float* %arg0, i32 50
  store float %304, float* %305
  %306 = getelementptr float* %arg1, i32 51
  %307 = load float* %306
  %308 = getelementptr float* %arg2, i32 51
  %309 = load float* %308
  %310 = fadd float %309, %307
  %311 = getelementptr float* %arg0, i32 51
  store float %310, float* %311
  %312 = getelementptr float* %arg1, i32 52
  %313 = load float* %312
  %314 = getelementptr float* %arg2, i32 52
  %315 = load float* %314
  %316 = fadd float %315, %313
  %317 = getelementptr float* %arg0, i32 52
  store float %316, float* %317
  %318 = getelementptr float* %arg1, i32 53
  %319 = load float* %318
  %320 = getelementptr float* %arg2, i32 53
  %321 = load float* %320
  %322 = fadd float %321, %319
  %323 = getelementptr float* %arg0, i32 53
  store float %322, float* %323
  %324 = getelementptr float* %arg1, i32 54
  %325 = load float* %324
  %326 = getelementptr float* %arg2, i32 54
  %327 = load float* %326
  %328 = fadd float %327, %325
  %329 = getelementptr float* %arg0, i32 54
  store float %328, float* %329
  %330 = getelementptr float* %arg1, i32 55
  %331 = load float* %330
  %332 = getelementptr float* %arg2, i32 55
  %333 = load float* %332
  %334 = fadd float %333, %331
  %335 = getelementptr float* %arg0, i32 55
  store float %334, float* %335
  %336 = getelementptr float* %arg1, i32 56
  %337 = load float* %336
  %338 = getelementptr float* %arg2, i32 56
  %339 = load float* %338
  %340 = fadd float %339, %337
  %341 = getelementptr float* %arg0, i32 56
  store float %340, float* %341
  %342 = getelementptr float* %arg1, i32 57
  %343 = load float* %342
  %344 = getelementptr float* %arg2, i32 57
  %345 = load float* %344
  %346 = fadd float %345, %343
  %347 = getelementptr float* %arg0, i32 57
  store float %346, float* %347
  %348 = getelementptr float* %arg1, i32 58
  %349 = load float* %348
  %350 = getelementptr float* %arg2, i32 58
  %351 = load float* %350
  %352 = fadd float %351, %349
  %353 = getelementptr float* %arg0, i32 58
  store float %352, float* %353
  %354 = getelementptr float* %arg1, i32 59
  %355 = load float* %354
  %356 = getelementptr float* %arg2, i32 59
  %357 = load float* %356
  %358 = fadd float %357, %355
  %359 = getelementptr float* %arg0, i32 59
  store float %358, float* %359
  %360 = getelementptr float* %arg1, i32 60
  %361 = load float* %360
  %362 = getelementptr float* %arg2, i32 60
  %363 = load float* %362
  %364 = fadd float %363, %361
  %365 = getelementptr float* %arg0, i32 60
  store float %364, float* %365
  %366 = getelementptr float* %arg1, i32 61
  %367 = load float* %366
  %368 = getelementptr float* %arg2, i32 61
  %369 = load float* %368
  %370 = fadd float %369, %367
  %371 = getelementptr float* %arg0, i32 61
  store float %370, float* %371
  %372 = getelementptr float* %arg1, i32 62
  %373 = load float* %372
  %374 = getelementptr float* %arg2, i32 62
  %375 = load float* %374
  %376 = fadd float %375, %373
  %377 = getelementptr float* %arg0, i32 62
  store float %376, float* %377
  %378 = getelementptr float* %arg1, i32 63
  %379 = load float* %378
  %380 = getelementptr float* %arg2, i32 63
  %381 = load float* %380
  %382 = fadd float %381, %379
  %383 = getelementptr float* %arg0, i32 63
  store float %382, float* %383
  ret void
}


More information about the llvm-dev mailing list