Your code is type unstable. Use a = UInt64(0).

On Wednesday, September 14, 2016 at 4:33:39 PM UTC+2, Ben Ward wrote:
>
> Hi,
>
> I've written a simple function:
>
> function testfun2()
>     a = 0
>     @inbounds @simd for i in UInt64(1):UInt64(1000)
>         i = i - ((i >> 1) & 0x5555555555555555)
>         a += ((i & 0x3333333333333333) + ((i >> 2) & 0x3333333333333333))
>     end
>     return a
> end
>
> I applies the same set of bit operations to a series of UInt64's and 
> accumulates a result.
>
> And know from the Intel blog on vectorisation, in the llvm code generated 
> by julia there is a set of instructions to look out for that indicate 
> vectorised code: vector.head and vector.ph:
>
> I'm wondering why I don't see those instructions in the llvm generated for 
> this function, I don't think I've violated any of the rules of writing 
> loops that can be vectorised:
>
> *julia> **@code_llvm testfun2()*
>
>
> define %jl_value_t* @julia_testfun2_70900() #0 {
>
> top:
>
>   %0 = call %jl_value_t*** @jl_get_ptls_states() #1
>
>   %1 = alloca [11 x %jl_value_t*], align 8
>
>   %.sub = getelementptr inbounds [11 x %jl_value_t*], [11 x %jl_value_t*]* 
> %1, i64 0, i64 0
>
>   %2 = getelementptr [11 x %jl_value_t*], [11 x %jl_value_t*]* %1, i64 0, 
> i64 8
>
>   %3 = getelementptr [11 x %jl_value_t*], [11 x %jl_value_t*]* %1, i64 0, 
> i64 2
>
>   %a = getelementptr [11 x %jl_value_t*], [11 x %jl_value_t*]* %1, i64 0, 
> i64 7
>
>   %4 = bitcast %jl_value_t** %2 to i8*
>
>   call void @llvm.memset.p0i8.i32(i8* %4, i8 0, i32 24, i32 8, i1 false)
>
>   %5 = bitcast [11 x %jl_value_t*]* %1 to i64*
>
>   %6 = bitcast %jl_value_t** %3 to i8*
>
>   call void @llvm.memset.p0i8.i64(i8* %6, i8 0, i64 40, i32 8, i1 false)
>
>   store i64 18, i64* %5, align 8
>
>   %7 = bitcast %jl_value_t*** %0 to i64*
>
>   %8 = load i64, i64* %7, align 8
>
>   %9 = getelementptr [11 x %jl_value_t*], [11 x %jl_value_t*]* %1, i64 0, 
> i64 1
>
>   %10 = bitcast %jl_value_t** %9 to i64*
>
>   store i64 %8, i64* %10, align 8
>
>   store %jl_value_t** %.sub, %jl_value_t*** %0, align 8
>
>   %"r#274" = alloca %UnitRange.6, align 8
>
>   store %jl_value_t* inttoptr (i64 4400218208 to %jl_value_t*), 
> %jl_value_t** %a, align 8
>
>   %11 = getelementptr inbounds %UnitRange.6, %UnitRange.6* %"r#274", i64 
> 0, i32 0
>
>   store i64 1, i64* %11, align 8
>
>   %12 = getelementptr inbounds %UnitRange.6, %UnitRange.6* %"r#274", i64 
> 0, i32 1
>
>   store i64 1000, i64* %12, align 8
>
>   %13 = call i64 @julia_simd_inner_length_70896(%UnitRange.6* nonnull 
> %"r#274", i64 0) #0
>
>   %14 = icmp eq i64 %13, 0
>
>   br i1 %14, label %L.backedge, label %if26.lr.ph
>
>
> L8:                                               ; preds = %if26
>
>   %15 = load %jl_value_t*, %jl_value_t** %a, align 8
>
>   store %jl_value_t* %15, %jl_value_t** %40, align 8
>
>   %16 = getelementptr inbounds %jl_value_t, %jl_value_t* %15, i64 -1, i32 0
>
>   %17 = bitcast %jl_value_t** %16 to i64*
>
>   %18 = load i64, i64* %17, align 8
>
>   %19 = and i64 %18, -16
>
>   %20 = inttoptr i64 %19 to %jl_value_t*
>
>   %21 = icmp eq %jl_value_t* %20, inttoptr (i64 4400088496 to %jl_value_t*)
>
>   br i1 %21, label %L11, label %L10
>
>
> L10:                                              ; preds = %L8
>
>   %22 = load i64, i64* %46, align 8
>
>   store i64 %22, i64* %47, align 8
>
>   %23 = and i64 %53, 3689348814741910323
>
>   %24 = lshr i64 %53, 2
>
>   %25 = and i64 %24, 3689348814741910323
>
>   %26 = add nuw nsw i64 %25, %23
>
>   store %jl_value_t* inttoptr (i64 4408276712 to %jl_value_t*), 
> %jl_value_t** %2, align 8
>
>   %27 = call %jl_value_t* @jl_box_uint64(i64 zeroext %26)
>
>   store %jl_value_t* %27, %jl_value_t** %44, align 8
>
>   %28 = call %jl_value_t* @jl_apply_generic(%jl_value_t** %2, i32 3)
>
>   store %jl_value_t* %28, %jl_value_t** %41, align 8
>
>   br label %L12
>
>
> L11:                                              ; preds = %L8, %if26
>
>   %"#temp#3.0" = phi %jl_value_t* [ inttoptr (i64 4409008592 to 
> %jl_value_t*), %if26 ], [ inttoptr (i64 4423075536 to %jl_value_t*), %L8 ]
>
>   store %jl_value_t* %"#temp#3.0", %jl_value_t** %42, align 8
>
>   %29 = load i64, i64* %46, align 8
>
>   store i64 %29, i64* %47, align 8
>
>   %30 = and i64 %53, 3689348814741910323
>
>   %31 = lshr i64 %53, 2
>
>   %32 = and i64 %31, 3689348814741910323
>
>   %33 = add nuw nsw i64 %32, %30
>
>   store %jl_value_t* inttoptr (i64 4408276712 to %jl_value_t*), 
> %jl_value_t** %2, align 8
>
>   %34 = call %jl_value_t* @jl_box_uint64(i64 zeroext %33)
>
>   store %jl_value_t* %34, %jl_value_t** %44, align 8
>
>   %35 = call %jl_value_t* @jl_invoke(%jl_value_t* %"#temp#3.0", 
> %jl_value_t** %2, i32 3)
>
>   store %jl_value_t* %35, %jl_value_t** %43, align 8
>
>   br label %L12
>
>
> L12:                                              ; preds = %L11, %L10
>
>   %storemerge.in.in = phi %jl_value_t* [ %28, %L10 ], [ %35, %L11 ]
>
>   %storemerge.in = bitcast %jl_value_t* %storemerge.in.in to i64*
>
>   %storemerge = load i64, i64* %storemerge.in, align 1
>
>   %36 = call %jl_value_t* @jl_box_uint64(i64 zeroext %storemerge)
>
>   store %jl_value_t* %36, %jl_value_t** %a, align 8
>
>   %37 = add nuw i64 %"i#277.040", 1
>
>   %exitcond = icmp eq i64 %37, %13
>
>   br i1 %exitcond, label %L.backedge.loopexit, label %if26
>
>
> L.backedge.loopexit:                              ; preds = %L12
>
>   br label %L.backedge
>
>
> L.backedge:                                       ; preds = 
> %L.backedge.loopexit, %top
>
>   %38 = load %jl_value_t*, %jl_value_t** %a, align 8
>
>   %39 = load i64, i64* %10, align 8
>
>   store i64 %39, i64* %7, align 8
>
>   ret %jl_value_t* %38
>
>
> if26.lr.ph:                                       ; preds = %top
>
>   %40 = getelementptr [11 x %jl_value_t*], [11 x %jl_value_t*]* %1, i64 0, 
> i64 3
>
>   %41 = getelementptr [11 x %jl_value_t*], [11 x %jl_value_t*]* %1, i64 0, 
> i64 4
>
>   %42 = getelementptr [11 x %jl_value_t*], [11 x %jl_value_t*]* %1, i64 0, 
> i64 5
>
>   %43 = getelementptr [11 x %jl_value_t*], [11 x %jl_value_t*]* %1, i64 0, 
> i64 6
>
>   %44 = getelementptr [11 x %jl_value_t*], [11 x %jl_value_t*]* %1, i64 0, 
> i64 10
>
>   %45 = getelementptr [11 x %jl_value_t*], [11 x %jl_value_t*]* %1, i64 0, 
> i64 9
>
>   %46 = bitcast %jl_value_t** %a to i64*
>
>   %47 = bitcast %jl_value_t** %45 to i64*
>
>   %.pre = load %jl_value_t*, %jl_value_t** %a, align 8
>
>   br label %if26
>
>
> if26:                                             ; preds = %L12, %
> if26.lr.ph
>
>   %48 = phi %jl_value_t* [ %.pre, %if26.lr.ph ], [ %36, %L12 ]
>
>   %"i#277.040" = phi i64 [ 0, %if26.lr.ph ], [ %37, %L12 ]
>
>   %49 = load i64, i64* %11, align 8
>
>   %50 = add i64 %49, %"i#277.040"
>
>   %51 = lshr i64 %50, 1
>
>   %52 = and i64 %51, 6148914691236517205
>
>   %53 = sub i64 %50, %52
>
>   store %jl_value_t* %48, %jl_value_t** %3, align 8
>
>   %54 = getelementptr inbounds %jl_value_t, %jl_value_t* %48, i64 -1, i32 0
>
>   %55 = bitcast %jl_value_t** %54 to i64*
>
>   %56 = load i64, i64* %55, align 8
>
>   %57 = and i64 %56, -16
>
>   %58 = inttoptr i64 %57 to %jl_value_t*
>
>   %59 = icmp eq %jl_value_t* %58, inttoptr (i64 4400097136 to %jl_value_t*)
>
>   br i1 %59, label %L11, label %L8
>
> }
>
>
>
> Thanks,
> Ben.
>

Reply via email to