{"action":"created","issue":{"url":"https://api.github.com/repos/johnmyleswhite/NullableArrays.jl/issues/24","labels_url":"https://api.github.com/repos/johnmyleswhite/NullableArrays.jl/issues/24/labels{/name}","comments_url":"https://api.github.com/repos/johnmyleswhite/NullableArrays.jl/issues/24/comments","events_url":"https://api.github.com/repos/johnmyleswhite/NullableArrays.jl/issues/24/events","html_url":"https://github.com/johnmyleswhite/NullableArrays.jl/pull/24","id":91528406,"number":24,"title":"Avoid branches for bits types","user":{"login":"johnmyleswhite","id":22064,"avatar_url":"https://avatars.githubusercontent.com/u/22064?v=3","gravatar_id":"","url":"https://api.github.com/users/johnmyleswhite","html_url":"https://github.com/johnmyleswhite","followers_url":"https://api.github.com/users/johnmyleswhite/followers","following_url":"https://api.github.com/users/johnmyleswhite/following{/other_user}","gists_url":"https://api.github.com/users/johnmyleswhite/gists{/gist_id}","starred_url":"https://api.github.com/users/johnmyleswhite/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/johnmyleswhite/subscriptions","organizations_url":"https://api.github.com/users/johnmyleswhite/orgs","repos_url":"https://api.github.com/users/johnmyleswhite/repos","events_url":"https://api.github.com/users/johnmyleswhite/events{/privacy}","received_events_url":"https://api.github.com/users/johnmyleswhite/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2015-06-27T23:26:02Z","updated_at":"2015-06-27T23:38:49Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/johnmyleswhite/NullableArrays.jl/pulls/24","html_url":"https://github.com/johnmyleswhite/NullableArrays.jl/pull/24","diff_url":"https://github.com/johnmyleswhite/NullableArrays.jl/pull/24.diff","patch_url":"https://github.com/johnmyleswhite/NullableArrays.jl/pull/24.patch"},"body":"This might resolve the SIMD problem seen by Jacob Quinn by removing a branch."},"comment":{"url":"https://api.github.com/repos/johnmyleswhite/NullableArrays.jl/issues/comments/116165941","html_url":"https://github.com/johnmyleswhite/NullableArrays.jl/pull/24#issuecomment-116165941","issue_url":"https://api.github.com/repos/johnmyleswhite/NullableArrays.jl/issues/24","id":116165941,"user":{"login":"johnmyleswhite","id":22064,"avatar_url":"https://avatars.githubusercontent.com/u/22064?v=3","gravatar_id":"","url":"https://api.github.com/users/johnmyleswhite","html_url":"https://github.com/johnmyleswhite","followers_url":"https://api.github.com/users/johnmyleswhite/followers","following_url":"https://api.github.com/users/johnmyleswhite/following{/other_user}","gists_url":"https://api.github.com/users/johnmyleswhite/gists{/gist_id}","starred_url":"https://api.github.com/users/johnmyleswhite/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/johnmyleswhite/subscriptions","organizations_url":"https://api.github.com/users/johnmyleswhite/orgs","repos_url":"https://api.github.com/users/johnmyleswhite/repos","events_url":"https://api.github.com/users/johnmyleswhite/events{/privacy}","received_events_url":"https://api.github.com/users/johnmyleswhite/received_events","type":"User","site_admin":false},"created_at":"2015-06-27T23:38:49Z","updated_at":"2015-06-27T23:38:49Z","body":"This PR potentially closes #22:\r\n\r\n```jl\r\n\r\njulia> using NullableArrays\r\n\r\njulia> A = rand(Float64, 5_000)\r\n5000-element Array{Float64,1}:\r\n 0.295619\r\n 0.442019\r\n 0.697729\r\n 0.768991\r\n 0.308044\r\n 0.474409\r\n 0.310926\r\n 0.18187 \r\n 0.922813\r\n 0.410064\r\n ⋮       \r\n 0.886561\r\n 0.604451\r\n 0.861349\r\n 0.996207\r\n 0.299021\r\n 0.680601\r\n 0.612236\r\n 0.899984\r\n 0.18355 \r\n\r\njulia> X = NullableArray(A)\r\n5000-element NullableArrays.NullableArray{Float64,1}:\r\n Nullable(0.2956185640383071) \r\n Nullable(0.4420188559870306) \r\n Nullable(0.6977285415172616) \r\n Nullable(0.7689912300039385) \r\n Nullable(0.30804399173516095)\r\n Nullable(0.47440908968517115)\r\n Nullable(0.3109263129940354) \r\n Nullable(0.18186991033146627)\r\n Nullable(0.9228134615542094) \r\n Nullable(0.41006395298879283)\r\n ⋮                            \r\n Nullable(0.8865608886699656) \r\n Nullable(0.6044508315049326) \r\n Nullable(0.8613489754657384) \r\n Nullable(0.9962074618446397) \r\n Nullable(0.2990205232481222) \r\n Nullable(0.680601043977068)  \r\n Nullable(0.6122363334993455) \r\n Nullable(0.8999842927990187) \r\n Nullable(0.1835500184618939) \r\n\r\njulia> function f(X::NullableArray)\r\n           res = 0.0\r\n           @simd for i in 1:length(X)\r\n               @inbounds res += X[i].value\r\n           end\r\n           return res\r\n       end\r\nf (generic function with 1 method)\r\n\r\njulia> @code_llvm(f(X))\r\n\r\ndefine double @julia_f_21672(%jl_value_t*) {\r\nL:\r\n  %1 = alloca [3 x %jl_value_t*], align 8\r\n  %.sub = getelementptr inbounds [3 x %jl_value_t*]* %1, i64 0, i64 0\r\n  %2 = getelementptr [3 x %jl_value_t*]* %1, i64 0, i64 2\r\n  store %jl_value_t* inttoptr (i64 2 to %jl_value_t*), %jl_value_t** %.sub, align 8\r\n  %3 = load %jl_value_t*** @jl_pgcstack, align 8\r\n  %4 = getelementptr [3 x %jl_value_t*]* %1, i64 0, i64 1\r\n  %.c = bitcast %jl_value_t** %3 to %jl_value_t*\r\n  store %jl_value_t* %.c, %jl_value_t** %4, align 8\r\n  store %jl_value_t** %.sub, %jl_value_t*** @jl_pgcstack, align 8\r\n  store %jl_value_t* null, %jl_value_t** %2, align 8\r\n  %5 = getelementptr inbounds %jl_value_t* %0, i64 0, i32 0\r\n  %6 = load %jl_value_t** %5, align 8\r\n  %7 = getelementptr inbounds %jl_value_t* %6, i64 1\r\n  %8 = bitcast %jl_value_t* %7 to i64*\r\n  %9 = load i64* %8, align 8\r\n  %10 = icmp sgt i64 %9, 0\r\n  %11 = select i1 %10, i64 %9, i64 0\r\n  %12 = call { i64, i1 } @llvm.ssub.with.overflow.i64(i64 %11, i64 1)\r\n  %13 = extractvalue { i64, i1 } %12, 1\r\n  br i1 %13, label %fail, label %pass\r\n\r\nfail:                                             ; preds = %L\r\n  %14 = load %jl_value_t** @jl_overflow_exception, align 8\r\n  call void @jl_throw_with_superfluous_argument(%jl_value_t* %14, i32 67)\r\n  unreachable\r\n\r\npass:                                             ; preds = %L\r\n  %15 = extractvalue { i64, i1 } %12, 0\r\n  %16 = call { i64, i1 } @llvm.sadd.with.overflow.i64(i64 %15, i64 1)\r\n  %17 = extractvalue { i64, i1 } %16, 1\r\n  br i1 %17, label %fail1, label %pass2\r\n\r\nfail1:                                            ; preds = %pass\r\n  %18 = load %jl_value_t** @jl_overflow_exception, align 8\r\n  call void @jl_throw_with_superfluous_argument(%jl_value_t* %18, i32 67)\r\n  unreachable\r\n\r\npass2:                                            ; preds = %pass\r\n  %19 = extractvalue { i64, i1 } %16, 0\r\n  %20 = icmp slt i64 %19, 1\r\n  br i1 %20, label %L21, label %if3\r\n\r\nif3:                                              ; preds = %pass2\r\n  %21 = load %jl_value_t** %5, align 8\r\n  %22 = bitcast %jl_value_t* %21 to i8**\r\n  %23 = load i8** %22, align 8\r\n  %24 = bitcast i8* %23 to double*\r\n  %n.vec = and i64 %19, -16\r\n  %cmp.zero = icmp eq i64 %n.vec, 0\r\n  br i1 %cmp.zero, label %middle.block, label %vector.body\r\n\r\nvector.body:                                      ; preds = %vector.body, %if3\r\n  %index = phi i64 [ %index.next, %vector.body ], [ 0, %if3 ]\r\n  %vec.phi = phi <4 x double> [ %33, %vector.body ], [ zeroinitializer, %if3 ]\r\n  %vec.phi25 = phi <4 x double> [ %34, %vector.body ], [ zeroinitializer, %if3 ]\r\n  %vec.phi26 = phi <4 x double> [ %35, %vector.body ], [ zeroinitializer, %if3 ]\r\n  %vec.phi27 = phi <4 x double> [ %36, %vector.body ], [ zeroinitializer, %if3 ]\r\n  %25 = getelementptr double* %24, i64 %index\r\n  %26 = bitcast double* %25 to <4 x double>*\r\n  %wide.load = load <4 x double>* %26, align 8\r\n  %.sum41 = or i64 %index, 4\r\n  %27 = getelementptr double* %24, i64 %.sum41\r\n  %28 = bitcast double* %27 to <4 x double>*\r\n  %wide.load28 = load <4 x double>* %28, align 8\r\n  %.sum42 = or i64 %index, 8\r\n  %29 = getelementptr double* %24, i64 %.sum42\r\n  %30 = bitcast double* %29 to <4 x double>*\r\n  %wide.load29 = load <4 x double>* %30, align 8\r\n  %.sum43 = or i64 %index, 12\r\n  %31 = getelementptr double* %24, i64 %.sum43\r\n  %32 = bitcast double* %31 to <4 x double>*\r\n  %wide.load30 = load <4 x double>* %32, align 8\r\n  %33 = fadd <4 x double> %vec.phi, %wide.load\r\n  %34 = fadd <4 x double> %vec.phi25, %wide.load28\r\n  %35 = fadd <4 x double> %vec.phi26, %wide.load29\r\n  %36 = fadd <4 x double> %vec.phi27, %wide.load30\r\n  %index.next = add i64 %index, 16\r\n  %37 = icmp eq i64 %index.next, %n.vec\r\n  br i1 %37, label %middle.block, label %vector.body\r\n\r\nmiddle.block:                                     ; preds = %vector.body, %if3\r\n  %resume.val = phi i64 [ 0, %if3 ], [ %n.vec, %vector.body ]\r\n  %rdx.vec.exit.phi = phi <4 x double> [ zeroinitializer, %if3 ], [ %33, %vector.body ]\r\n  %rdx.vec.exit.phi33 = phi <4 x double> [ zeroinitializer, %if3 ], [ %34, %vector.body ]\r\n  %rdx.vec.exit.phi34 = phi <4 x double> [ zeroinitializer, %if3 ], [ %35, %vector.body ]\r\n  %rdx.vec.exit.phi35 = phi <4 x double> [ zeroinitializer, %if3 ], [ %36, %vector.body ]\r\n  %bin.rdx = fadd <4 x double> %rdx.vec.exit.phi33, %rdx.vec.exit.phi\r\n  %bin.rdx36 = fadd <4 x double> %rdx.vec.exit.phi34, %bin.rdx\r\n  %bin.rdx37 = fadd <4 x double> %rdx.vec.exit.phi35, %bin.rdx36\r\n  %rdx.shuf = shufflevector <4 x double> %bin.rdx37, <4 x double> undef, <4 x i32> <i32 2, i32 3, i32 undef, i32 undef>\r\n  %bin.rdx38 = fadd <4 x double> %bin.rdx37, %rdx.shuf\r\n  %rdx.shuf39 = shufflevector <4 x double> %bin.rdx38, <4 x double> undef, <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef>\r\n  %bin.rdx40 = fadd <4 x double> %bin.rdx38, %rdx.shuf39\r\n  %38 = extractelement <4 x double> %bin.rdx40, i32 0\r\n  %cmp.n = icmp eq i64 %19, %resume.val\r\n  br i1 %cmp.n, label %L21, label %L5\r\n\r\nL5:                                               ; preds = %L5, %middle.block\r\n  %\"##i#9126.0\" = phi i64 [ %42, %L5 ], [ %resume.val, %middle.block ]\r\n  %res.1 = phi double [ %41, %L5 ], [ %38, %middle.block ]\r\n  %39 = getelementptr double* %24, i64 %\"##i#9126.0\"\r\n  %40 = load double* %39, align 8\r\n  %41 = fadd fast double %res.1, %40\r\n  %42 = add i64 %\"##i#9126.0\", 1\r\n  %exitcond = icmp eq i64 %42, %19\r\n  br i1 %exitcond, label %L21, label %L5\r\n\r\nL21:                                              ; preds = %L5, %middle.block, %pass2\r\n  %res.3 = phi double [ 0.000000e+00, %pass2 ], [ %41, %L5 ], [ %38, %middle.block ]\r\n  %43 = load %jl_value_t** %4, align 8\r\n  %44 = getelementptr inbounds %jl_value_t* %43, i64 0, i32 0\r\n  store %jl_value_t** %44, %jl_value_t*** @jl_pgcstack, align 8\r\n  ret double %res.3\r\n}\r\n\r\njulia> \r\n```\r\n"}}