julia> CUDA.@device_code_llvm map(y -> 2 // 10 * y, CUDA.ones(5_000_000));
; PTX CompilerJob of MethodInstance for (::GPUArrays.var"#gpu_broadcast_kernel_linear#_copyto!##1")(::KernelAbstractions.CompilerMetadata{KernelAbstractions.NDIteration.DynamicSize, KernelAbstractions.NDIteration.DynamicCheck, Nothing, CartesianIndices{1, Tuple{Base.OneTo{Int64}}}, KernelAbstractions.NDIteration.NDRange{1, KernelAbstractions.NDIteration.DynamicSize, KernelAbstractions.NDIteration.DynamicSize, CartesianIndices{1, Tuple{Base.OneTo{Int64}}}, CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}}, ::CuDeviceVector{Float32, 1}, ::Base.Broadcast.Broadcasted{CUDA.CuArrayStyle{1, CUDA.DeviceMemory}, Tuple{Base.OneTo{Int64}}, var"#427#428", Tuple{Base.Broadcast.Extruded{CuDeviceVector{Float32, 1}, Tuple{Bool}, Tuple{Int64}}}}) for sm_86
; @ none within `gpu_broadcast_kernel_linear`
define ptx_kernel void @_Z27gpu_broadcast_kernel_linear16CompilerMetadataI11DynamicSize12DynamicCheckv16CartesianIndicesILi1E5TupleI5OneToI5Int64EEE7NDRangeILi1ES0_S0_S8_S8_EE13CuDeviceArrayI7Float32Li1ELi1EE11BroadcastedI12CuArrayStyleILi1E12DeviceMemoryES7_4_427S3_I8ExtrudedISE_S3_I4BoolES3_IS5_EEEE({ ptr, i32 } %state, { [1 x [1 x [1 x i64]]], [2 x [1 x [1 x [1 x i64]]]] } %"__ctx__::CompilerMetadata", { ptr addrspace(1), i64, [1 x i64], i64 } %"dest::CuDeviceArray", { [1 x { { ptr addrspace(1), i64, [1 x i64], i64 }, [1 x i8], [1 x i64] }], [1 x [1 x i64]] } %"bc::Broadcasted") local_unnamed_addr {
conversion:
%"__ctx__::CompilerMetadata.fca.0.0.0.0.extract" = extractvalue { [1 x [1 x [1 x i64]]], [2 x [1 x [1 x [1 x i64]]]] } %"__ctx__::CompilerMetadata", 0, 0, 0, 0
%"__ctx__::CompilerMetadata.fca.1.0.0.0.0.extract" = extractvalue { [1 x [1 x [1 x i64]]], [2 x [1 x [1 x [1 x i64]]]] } %"__ctx__::CompilerMetadata", 1, 0, 0, 0, 0
%"__ctx__::CompilerMetadata.fca.1.1.0.0.0.extract" = extractvalue { [1 x [1 x [1 x i64]]], [2 x [1 x [1 x [1 x i64]]]] } %"__ctx__::CompilerMetadata", 1, 1, 0, 0, 0
%"dest::CuDeviceArray.fca.0.extract" = extractvalue { ptr addrspace(1), i64, [1 x i64], i64 } %"dest::CuDeviceArray", 0
%sret_box = alloca [2 x i64], align 8
%0 = call i32 @llvm.nvvm.read.ptx.sreg.ctaid.x()
%1 = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
%2 = add nuw nsw i32 %1, 1
%3 = icmp sgt i64 %"__ctx__::CompilerMetadata.fca.1.0.0.0.0.extract", 0
call void @llvm.assume(i1 %3)
%4 = icmp sgt i64 %"__ctx__::CompilerMetadata.fca.1.1.0.0.0.extract", 0
call void @llvm.assume(i1 %4)
%5 = zext nneg i32 %2 to i64
%6 = zext nneg i32 %0 to i64
%7 = mul i64 %"__ctx__::CompilerMetadata.fca.1.1.0.0.0.extract", %6
%8 = add i64 %7, %5
%9 = icmp slt i64 %8, 1
%10 = icmp sgt i64 %8, %"__ctx__::CompilerMetadata.fca.0.0.0.0.extract"
%.not18 = or i1 %9, %10
br i1 %.not18, label %L360, label %L129
L129: ; preds = %conversion
%"bc::Broadcasted.fca.0.0.2.0.extract" = extractvalue { [1 x { { ptr addrspace(1), i64, [1 x i64], i64 }, [1 x i8], [1 x i64] }], [1 x [1 x i64]] } %"bc::Broadcasted", 0, 0, 2, 0
%"bc::Broadcasted.fca.0.0.1.0.extract" = extractvalue { [1 x { { ptr addrspace(1), i64, [1 x i64], i64 }, [1 x i8], [1 x i64] }], [1 x [1 x i64]] } %"bc::Broadcasted", 0, 0, 1, 0
%"bc::Broadcasted.fca.0.0.0.0.extract" = extractvalue { [1 x { { ptr addrspace(1), i64, [1 x i64], i64 }, [1 x i8], [1 x i64] }], [1 x [1 x i64]] } %"bc::Broadcasted", 0, 0, 0, 0
; ┌ @ /home/efaulha2/.julia/packages/KernelAbstractions/lGrz7/src/macros.jl:324 within `macro expansion`
; │┌ @ broadcast.jl:616 within `getindex`
; ││┌ @ broadcast.jl:620 within `_getindex`
; │││┌ @ broadcast.jl:671 within `_broadcast_getindex`
; ││││┌ @ broadcast.jl:696 within `_getindex`
; │││││┌ @ broadcast.jl:665 within `_broadcast_getindex`
; ││││││┌ @ broadcast.jl:595 within `newindex`
; │││││││┌ @ essentials.jl:799 within `ifelse`
%11 = and i8 %"bc::Broadcasted.fca.0.0.1.0.extract", 1
%.not = icmp eq i8 %11, 0
%12 = select i1 %.not, i64 %"bc::Broadcasted.fca.0.0.2.0.extract", i64 %8
; ││││││└└
; ││││││┌ @ /home/efaulha2/.julia/packages/CUDA/UurkZ/src/device/array.jl:175 within `getindex`
; │││││││┌ @ /home/efaulha2/.julia/packages/CUDA/UurkZ/src/device/array.jl:90 within `arrayref`
; ││││││││┌ @ /home/efaulha2/.julia/packages/CUDA/UurkZ/src/device/array.jl:96 within `arrayref_bits`
; │││││││││┌ @ /home/efaulha2/.julia/packages/LLVM/iza6e/src/interop/pointer.jl:85 within `unsafe_load`
; ││││││││││┌ @ none within `pointerref`
; │││││││││││┌ @ none within `macro expansion` @ /home/efaulha2/.julia/packages/LLVM/iza6e/src/interop/base.jl:39
%13 = getelementptr float, ptr addrspace(1) %"bc::Broadcasted.fca.0.0.0.0.extract", i64 %12
%14 = getelementptr float, ptr addrspace(1) %13, i64 -1
%15 = load float, ptr addrspace(1) %14, align 4
; ││││└└└└└└└└
; ││││ @ broadcast.jl:672 within `_broadcast_getindex`
; ││││┌ @ broadcast.jl:699 within `_broadcast_getindex_evalf`
; │││││┌ @ REPL[90]:1 within `#427`
; ││││││┌ @ rational.jl:91 within `//`
; │││││││┌ @ rational.jl:48 within `Rational` @ rational.jl:43
call fastcc void @julia_divgcd_100531({ ptr, i32 } %state, ptr %sret_box, i64 2, i64 10)
; ││││││││┌ @ tuple.jl:162 within `indexed_iterate`
%"sret_box[2]_ptr" = getelementptr inbounds i8, ptr %sret_box, i64 8
; ││││││││└
; ││││││││ @ rational.jl:48 within `Rational` @ rational.jl:44
; ││││││││┌ @ rational.jl:21 within `checked_den`
; │││││││││┌ @ int.jl:139 within `signbit`
; ││││││││││┌ @ int.jl:83 within `<`
%"sret_box[2]_ptr.unbox" = load i64, ptr %"sret_box[2]_ptr", align 8
%16 = icmp sgt i64 %"sret_box[2]_ptr.unbox", -1
; │││││││││└└
br i1 %16, label %L308.L330_crit_edge, label %L313
L308.L330_crit_edge: ; preds = %L129
%value_phi.in.sroa.speculate.load.L308.L330_crit_edge = load i64, ptr %sret_box, align 8
br label %L336
L313: ; preds = %L129
; │││││││││ @ rational.jl:22 within `checked_den`
; │││││││││┌ @ checked.jl:95 within `checked_neg`
; ││││││││││┌ @ checked.jl:231 within `checked_sub`
; │││││││││││┌ @ checked.jl:203 within `sub_with_overflow`
%17 = call { i64, i1 } @llvm.ssub.with.overflow.i64(i64 0, i64 %"sret_box[2]_ptr.unbox")
%18 = extractvalue { i64, i1 } %17, 0
%19 = extractvalue { i64, i1 } %17, 1
; │││││││││││└
; │││││││││││ @ checked.jl:232 within `checked_sub`
br i1 %19, label %L317, label %L321
L317: ; preds = %L313
call fastcc void @julia_throw_overflowerr_binaryop_100524({ ptr, i32 } %state)
unreachable
L321: ; preds = %L313
; │││││││││└└
; │││││││││ @ rational.jl:23 within `checked_den`
; │││││││││┌ @ checked.jl:95 within `checked_neg`
; ││││││││││┌ @ checked.jl:231 within `checked_sub`
; │││││││││││┌ @ checked.jl:203 within `sub_with_overflow`
%sret_box.unbox = load i64, ptr %sret_box, align 8
%20 = call { i64, i1 } @llvm.ssub.with.overflow.i64(i64 0, i64 %sret_box.unbox)
%21 = extractvalue { i64, i1 } %20, 1
; │││││││││││└
; │││││││││││ @ checked.jl:232 within `checked_sub`
br i1 %21, label %L325, label %L329
L325: ; preds = %L321
call fastcc void @julia_throw_overflowerr_binaryop_100524({ ptr, i32 } %state)
unreachable
L329: ; preds = %L321
; │││││││││││ @ checked.jl:231 within `checked_sub`
; │││││││││││┌ @ checked.jl:203 within `sub_with_overflow`
%22 = extractvalue { i64, i1 } %20, 0
; │││││││││││└
; │││││││││││ @ checked.jl:232 within `checked_sub`
br label %L336
L336: ; preds = %L329, %L308.L330_crit_edge
%value_phi.in.sroa.speculated = phi i64 [ %22, %L329 ], [ %value_phi.in.sroa.speculate.load.L308.L330_crit_edge, %L308.L330_crit_edge ]
%value_phi46 = phi i64 [ %18, %L329 ], [ %"sret_box[2]_ptr.unbox", %L308.L330_crit_edge ]
; ││││││└└└└└
; ││││││┌ @ promotion.jl:434 within `*`
; │││││││┌ @ promotion.jl:404 within `promote`
; ││││││││┌ @ promotion.jl:379 within `_promote`
; │││││││││┌ @ number.jl:7 within `convert`
; ││││││││││┌ @ rational.jl:164 within `AbstractFloat`
; │││││││││││┌ @ number.jl:7 within `convert`
; ││││││││││││┌ @ float.jl:245 within `Float32`
%23 = sitofp i64 %value_phi.in.sroa.speculated to float
%24 = sitofp i64 %value_phi46 to float
; │││││││││││└└
; │││││││││││┌ @ float.jl:498 within `/`
%25 = fdiv float %23, %24
; │││││││└└└└└
; │││││││ @ promotion.jl:434 within `*` @ float.jl:497
%26 = fmul float %15, %25
; │└└└└└└
; │┌ @ /home/efaulha2/.julia/packages/CUDA/UurkZ/src/device/array.jl:177 within `setindex!`
; ││┌ @ /home/efaulha2/.julia/packages/CUDA/UurkZ/src/device/array.jl:135 within `arrayset`
; │││┌ @ /home/efaulha2/.julia/packages/CUDA/UurkZ/src/device/array.jl:142 within `arrayset_bits`
; ││││┌ @ /home/efaulha2/.julia/packages/LLVM/iza6e/src/interop/pointer.jl:88 within `unsafe_store!`
; │││││┌ @ none within `pointerset`
; ││││││┌ @ none within `macro expansion` @ /home/efaulha2/.julia/packages/LLVM/iza6e/src/interop/base.jl:39
%27 = getelementptr float, ptr addrspace(1) %"dest::CuDeviceArray.fca.0.extract", i64 %8
%28 = getelementptr float, ptr addrspace(1) %27, i64 -1
store float %26, ptr addrspace(1) %28, align 4
; │││└└└└
; │││ @ /home/efaulha2/.julia/packages/CUDA/UurkZ/src/device/array.jl:137 within `arrayset`
br label %L360
L360: ; preds = %L336, %conversion
; │└└
ret void
; └
}
MWE:
Note that this has nothing to do with FP64. Here is the FP64 version:
Note that I get similar problems in larger kernels. Just using a simple
Rationallike this makes the whole kernel 2x slower.LLVM for y * 2 / 10
LLVM for 2 // 10 * y
Here is my versioninfo: