-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Windows Nightly Regression #14285
Comments
Reduced: struct Time2
def initialize(@seconds : Int64)
@nanoseconds = uninitialized UInt32[3]
end
def <(other : Time2) : Bool
@seconds < other.@seconds
end
end
class Constraints::Range
def initialize(@min : Int128 | Time2 | Nil)
end
end
def validate(value : Time2, constraint) : Nil
min = constraint.@min
if min.is_a?(Time2?)
if min
if value < min
LibC.printf("foo\n")
end
end
end
end
value = Time2.new(123)
constraint = Constraints::Range.new(Time2.new(45))
validate(value, constraint) This generates the following fragment for the then2: ; preds = %then
%25 = getelementptr inbounds %"(Int128 | Time2 | Nil)", ptr %min, i32 0, i32 0
%26 = load i32, ptr %25, align 4
%27 = getelementptr inbounds %"(Int128 | Time2 | Nil)", ptr %min, i32 0, i32 1
%28 = load %Time2, ptr %27, align 8 ; underaligned load occurs here
%29 = call i1 @"*Time2#<<Time2>:Bool"(ptr %value1, %Time2 %28)
br i1 %29, label %then4, label %else5 It looks like all loads that go through |
The problem is that the crystal/src/compiler/crystal/codegen/call.cr Lines 85 to 99 in c67883c
It was mostly coincidence that underaligned operations for smaller sizes were working before on x86-64. With actual 16-byte-aligned types this is not the case anymore. |
Changing the alignments in the emitted LLVM IR manually did not help. Instead it looks like the problem is with how the new if min.is_a?(Time2?)
if min # this downcast
# ... %"(Time2 | Nil)" = type { i32, [3 x i64] }
%11 = getelementptr inbounds %"(Int128 | Time2 | Nil)", ptr %min, i32 0, i32 0
%12 = load i32, ptr %11, align 4
%14 = getelementptr inbounds %"(Time2 | Nil)", ptr %0, i32 0, i32 0
store i32 %12, ptr %14, align 4
%15 = getelementptr inbounds %"(Time2 | Nil)", ptr %0, i32 0, i32 1
%16 = getelementptr inbounds %"(Int128 | Time2 | Nil)", ptr %min, i32 0, i32 1
call void @llvm.memcpy.p0.p0.i64(ptr align 8 %15, ptr align 16 %16, i64 32, i1 false) ; this 32 So we are corrupting the stack by copying 32 bytes to the data field of a We probably don't need to touch the load / store alignments for now. Maybe LLVM cannot prove that some |
Will try to reduce more, but this is what I was able to come up with so far:
Previous nightly version:
Latest nightly version:
Seemingly is related to #14277 🤷.
The text was updated successfully, but these errors were encountered: