Open waywardmonkeys opened 9 years ago
Changing this to be correct with type conversions and all is well (at compilation time):
define common-extensions class-test <arithmetic-domain-error> ()
check-condition("sqrt(-1.0) signals <arithmetic-domain-error>",
<arithmetic-domain-error>,
begin
let x :: <single-float> = -1.0s0;
primitive-raw-as-single-float(primitive-single-float-sqrt(primitive-single-float-as-raw(x)));
end);
end class-test <arithmetic-domain-error>;
That generated this IR:
define internal fastcc %struct.MV @Kanonymous_of_test_protocol_definitionF187I(i8* %.next, i8* %.function) {
bb.entry:
%0 = call float @llvm.sqrt.f32(float -1.000000e+00) #2, !dbg !242
%1 = call fastcc %KLsingle_floatGVKd* @primitive_raw_as_single_float(float %0), !dbg !242
%2 = bitcast %KLsingle_floatGVKd* %1 to i8*, !dbg !242
%3 = insertvalue %struct.MV undef, i8* %2, 0, !dbg !243
%4 = insertvalue %struct.MV %3, i8 1, 1, !dbg !243
ret %struct.MV %4, !dbg !243
}
(which didn't end up signaling the condition I was testing for ...)
I imagine llvm.sqrt.f32 gets lowered to the standard sqrtf() function, which probably has its own domain checks so that it "returns a NaN and generates a domain error for x < 0."
Well, on Mac OS X, this generates the right FP trap:
#include <fenv.h>
#include <math.h>
#include <stdio.h>
int main (int argc, char **argv)
{
feclearexcept(FE_ALL_EXCEPT);
fenv_t fenv;
fegetenv(&fenv);
fenv.__control &= ~(FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INVALID);
fenv.__mxcsr &= ~((FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INVALID) << 7);
fesetenv(&fenv);
printf("%f\n", sqrt(-1.0 * argc));
return 0;
}
When compiling this code:
I get:
The generated LLVM IR was: