Skip to content

Commit b93434c

Browse files
committed
Better behavior for Boolean ConstInts.
1 parent 45787ea commit b93434c

File tree

2 files changed

+20
-6
lines changed

2 files changed

+20
-6
lines changed

src/core/value/constant.jl

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,12 @@ const WideInteger = Union{Int64, UInt64}
4646
ConstantInt(typ::IntegerType, val::WideInteger, signed=false) =
4747
ConstantInt(API.LLVMConstInt(typ, reinterpret(Culonglong, val),
4848
convert(Bool, signed)))
49-
const SmallInteger = Union{Int8, Int16, Int32, UInt8, UInt16, UInt32}
49+
const SmallInteger = Union{Core.Bool, Int8, Int16, Int32, UInt8, UInt16, UInt32}
5050
ConstantInt(typ::IntegerType, val::SmallInteger, signed=false) =
5151
ConstantInt(typ, convert(Int64, val), signed)
5252

5353
function ConstantInt(typ::IntegerType, val::Integer, signed=false)
54-
valbits = ceil(Int, log2(abs(val))) + 1
54+
valbits = ceil(Int, log2(abs(val))) + 1 # FIXME: doesn't work for val=0
5555
numwords = ceil(Int, valbits / 64)
5656
words = Vector{Culonglong}(undef, numwords)
5757
for i in 1:numwords
@@ -67,12 +67,18 @@ function ConstantInt(val::T, ctx::Context) where T<:SizeableInteger
6767
return ConstantInt(typ, val, T<:Signed)
6868
end
6969

70+
# Booleans are encoded with a single bit, so we can't use sizeof
71+
ConstantInt(val::Core.Bool, ctx::Context) = ConstantInt(Int1Type(ctx), val ? 1 : 0)
72+
7073
Base.convert(::Type{T}, val::ConstantInt) where {T<:Unsigned} =
7174
convert(T, API.LLVMConstIntGetZExtValue(val))
7275

7376
Base.convert(::Type{T}, val::ConstantInt) where {T<:Signed} =
7477
convert(T, API.LLVMConstIntGetSExtValue(val))
7578

79+
# Booleans aren't Signed or Unsigned
80+
Base.convert(::Type{Core.Bool}, val::ConstantInt) = convert(Int, val) != 0
81+
7682

7783
@checked struct ConstantFP <: Constant
7884
ref::API.LLVMValueRef
@@ -146,8 +152,11 @@ function ConstantArray(data::AbstractArray{<:Constant,N},
146152
end
147153

148154
# shorthands with arrays of plain Julia data
155+
# FIXME: duplicates the ConstantInt/ConstantFP conversion rules (to support empty arrays)
149156
ConstantArray(data::AbstractArray{T,N}, ctx::Context=GlobalContext()) where {T<:Integer,N} =
150157
ConstantArray(ConstantInt.(data, Ref(ctx)), IntType(sizeof(T)*8, ctx))
158+
ConstantArray(data::AbstractArray{Core.Bool,N}, ctx::Context=GlobalContext()) where {N} =
159+
ConstantArray(ConstantInt.(data, Ref(ctx)), Int1Type(ctx))
151160
ConstantArray(data::AbstractArray{Float16,N}, ctx::Context=GlobalContext()) where {N} =
152161
ConstantArray(ConstantFP.(data, Ref(ctx)), HalfType(ctx))
153162
ConstantArray(data::AbstractArray{Float32,N}, ctx::Context=GlobalContext()) where {N} =
@@ -224,10 +233,7 @@ function ConstantStruct(value::T, ctx::Context=GlobalContext(); name=String(name
224233
for fieldname in fieldnames(T)
225234
field = getfield(value, fieldname)
226235

227-
if isa(field, Core.Bool)
228-
typ = LLVM.Int1Type(ctx)
229-
push!(constants, ConstantInt(typ, Int(field)))
230-
elseif isa(field, Integer)
236+
if isa(field, Integer)
231237
push!(constants, ConstantInt(field, ctx))
232238
elseif isa(field, AbstractFloat)
233239
push!(constants, ConstantFP(field, ctx))

test/core.jl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,14 @@ Context() do ctx
371371
constval = ConstantInt(UInt32(1), ctx)
372372
@test convert(UInt, constval) == 1
373373
end
374+
let
375+
constval = ConstantInt(false, ctx)
376+
@test llvmtype(constval) == LLVM.Int1Type(ctx)
377+
@test !convert(Bool, constval)
378+
379+
constval = ConstantInt(true, ctx)
380+
@test convert(Bool, constval)
381+
end
374382

375383
# issue #81
376384
for T in [Int32, UInt32, Int64, UInt64]

0 commit comments

Comments
 (0)