Skip to content

Commit cb35da5

Browse files
committed
Try #651:
2 parents 4dd9db4 + 32ff742 commit cb35da5

File tree

2 files changed

+84
-91
lines changed

2 files changed

+84
-91
lines changed

lib/llvm-backend/src/code.rs

+50-91
Original file line numberDiff line numberDiff line change
@@ -360,45 +360,6 @@ fn trap_if_zero(
360360
builder.position_at_end(&shouldnt_trap_block);
361361
}
362362

363-
// Replaces any NaN with the canonical QNaN, otherwise leaves the value alone.
364-
fn canonicalize_nans(
365-
builder: &Builder,
366-
intrinsics: &Intrinsics,
367-
value: BasicValueEnum,
368-
) -> BasicValueEnum {
369-
let f_ty = value.get_type();
370-
let canonicalized = if f_ty.is_vector_type() {
371-
let value = value.into_vector_value();
372-
let f_ty = f_ty.into_vector_type();
373-
let zero = f_ty.const_zero();
374-
let nan_cmp = builder.build_float_compare(FloatPredicate::UNO, value, zero, "nan");
375-
let canonical_qnan = f_ty
376-
.get_element_type()
377-
.into_float_type()
378-
.const_float(std::f64::NAN);
379-
let canonical_qnan = splat_vector(
380-
builder,
381-
intrinsics,
382-
canonical_qnan.as_basic_value_enum(),
383-
f_ty,
384-
"",
385-
);
386-
builder
387-
.build_select(nan_cmp, canonical_qnan, value, "")
388-
.as_basic_value_enum()
389-
} else {
390-
let value = value.into_float_value();
391-
let f_ty = f_ty.into_float_type();
392-
let zero = f_ty.const_zero();
393-
let nan_cmp = builder.build_float_compare(FloatPredicate::UNO, value, zero, "nan");
394-
let canonical_qnan = f_ty.const_float(std::f64::NAN);
395-
builder
396-
.build_select(nan_cmp, canonical_qnan, value, "")
397-
.as_basic_value_enum()
398-
};
399-
canonicalized
400-
}
401-
402363
fn resolve_memory_ptr(
403364
builder: &Builder,
404365
intrinsics: &Intrinsics,
@@ -2163,120 +2124,120 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
21632124
***************************/
21642125
Operator::F32Add | Operator::F64Add => {
21652126
let (v1, v2) = state.pop2()?;
2166-
let v1 = canonicalize_nans(builder, intrinsics, v1);
2167-
let v2 = canonicalize_nans(builder, intrinsics, v2);
21682127
let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
21692128
let res = builder.build_float_add(v1, v2, &state.var_name());
21702129
state.push1(res);
21712130
}
21722131
Operator::F32x4Add => {
21732132
let (v1, v2) = state.pop2()?;
2174-
let v1 = builder.build_bitcast(v1, intrinsics.f32x4_ty, "");
2175-
let v2 = builder.build_bitcast(v2, intrinsics.f32x4_ty, "");
2176-
let v1 = canonicalize_nans(builder, intrinsics, v1);
2177-
let v2 = canonicalize_nans(builder, intrinsics, v2);
2178-
let (v1, v2) = (v1.into_vector_value(), v2.into_vector_value());
2133+
let v1 = builder
2134+
.build_bitcast(v1, intrinsics.f32x4_ty, "")
2135+
.into_vector_value();
2136+
let v2 = builder
2137+
.build_bitcast(v2, intrinsics.f32x4_ty, "")
2138+
.into_vector_value();
21792139
let res = builder.build_float_add(v1, v2, &state.var_name());
21802140
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
21812141
state.push1(res);
21822142
}
21832143
Operator::F64x2Add => {
21842144
let (v1, v2) = state.pop2()?;
2185-
let v1 = builder.build_bitcast(v1, intrinsics.f64x2_ty, "");
2186-
let v2 = builder.build_bitcast(v2, intrinsics.f64x2_ty, "");
2187-
let v1 = canonicalize_nans(builder, intrinsics, v1);
2188-
let v2 = canonicalize_nans(builder, intrinsics, v2);
2189-
let (v1, v2) = (v1.into_vector_value(), v2.into_vector_value());
2145+
let v1 = builder
2146+
.build_bitcast(v1, intrinsics.f64x2_ty, "")
2147+
.into_vector_value();
2148+
let v2 = builder
2149+
.build_bitcast(v2, intrinsics.f64x2_ty, "")
2150+
.into_vector_value();
21902151
let res = builder.build_float_add(v1, v2, &state.var_name());
21912152
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
21922153
state.push1(res);
21932154
}
21942155
Operator::F32Sub | Operator::F64Sub => {
21952156
let (v1, v2) = state.pop2()?;
2196-
let v1 = canonicalize_nans(builder, intrinsics, v1);
2197-
let v2 = canonicalize_nans(builder, intrinsics, v2);
21982157
let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
21992158
let res = builder.build_float_sub(v1, v2, &state.var_name());
22002159
state.push1(res);
22012160
}
22022161
Operator::F32x4Sub => {
22032162
let (v1, v2) = state.pop2()?;
2204-
let v1 = builder.build_bitcast(v1, intrinsics.f32x4_ty, "");
2205-
let v2 = builder.build_bitcast(v2, intrinsics.f32x4_ty, "");
2206-
let v1 = canonicalize_nans(builder, intrinsics, v1);
2207-
let v2 = canonicalize_nans(builder, intrinsics, v2);
2208-
let (v1, v2) = (v1.into_vector_value(), v2.into_vector_value());
2163+
let v1 = builder
2164+
.build_bitcast(v1, intrinsics.f32x4_ty, "")
2165+
.into_vector_value();
2166+
let v2 = builder
2167+
.build_bitcast(v2, intrinsics.f32x4_ty, "")
2168+
.into_vector_value();
22092169
let res = builder.build_float_sub(v1, v2, &state.var_name());
22102170
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
22112171
state.push1(res);
22122172
}
22132173
Operator::F64x2Sub => {
22142174
let (v1, v2) = state.pop2()?;
2215-
let v1 = builder.build_bitcast(v1, intrinsics.f64x2_ty, "");
2216-
let v2 = builder.build_bitcast(v2, intrinsics.f64x2_ty, "");
2217-
let v1 = canonicalize_nans(builder, intrinsics, v1);
2218-
let v2 = canonicalize_nans(builder, intrinsics, v2);
2219-
let (v1, v2) = (v1.into_vector_value(), v2.into_vector_value());
2175+
let v1 = builder
2176+
.build_bitcast(v1, intrinsics.f64x2_ty, "")
2177+
.into_vector_value();
2178+
let v2 = builder
2179+
.build_bitcast(v2, intrinsics.f64x2_ty, "")
2180+
.into_vector_value();
22202181
let res = builder.build_float_sub(v1, v2, &state.var_name());
22212182
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
22222183
state.push1(res);
22232184
}
22242185
Operator::F32Mul | Operator::F64Mul => {
22252186
let (v1, v2) = state.pop2()?;
2226-
let v1 = canonicalize_nans(builder, intrinsics, v1);
2227-
let v2 = canonicalize_nans(builder, intrinsics, v2);
22282187
let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
22292188
let res = builder.build_float_mul(v1, v2, &state.var_name());
22302189
state.push1(res);
22312190
}
22322191
Operator::F32x4Mul => {
22332192
let (v1, v2) = state.pop2()?;
2234-
let v1 = builder.build_bitcast(v1, intrinsics.f32x4_ty, "");
2235-
let v2 = builder.build_bitcast(v2, intrinsics.f32x4_ty, "");
2236-
let v1 = canonicalize_nans(builder, intrinsics, v1);
2237-
let v2 = canonicalize_nans(builder, intrinsics, v2);
2238-
let (v1, v2) = (v1.into_vector_value(), v2.into_vector_value());
2193+
let v1 = builder
2194+
.build_bitcast(v1, intrinsics.f32x4_ty, "")
2195+
.into_vector_value();
2196+
let v2 = builder
2197+
.build_bitcast(v2, intrinsics.f32x4_ty, "")
2198+
.into_vector_value();
22392199
let res = builder.build_float_mul(v1, v2, &state.var_name());
22402200
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
22412201
state.push1(res);
22422202
}
22432203
Operator::F64x2Mul => {
22442204
let (v1, v2) = state.pop2()?;
2245-
let v1 = builder.build_bitcast(v1, intrinsics.f64x2_ty, "");
2246-
let v2 = builder.build_bitcast(v2, intrinsics.f64x2_ty, "");
2247-
let v1 = canonicalize_nans(builder, intrinsics, v1);
2248-
let v2 = canonicalize_nans(builder, intrinsics, v2);
2249-
let (v1, v2) = (v1.into_vector_value(), v2.into_vector_value());
2205+
let v1 = builder
2206+
.build_bitcast(v1, intrinsics.f64x2_ty, "")
2207+
.into_vector_value();
2208+
let v2 = builder
2209+
.build_bitcast(v2, intrinsics.f64x2_ty, "")
2210+
.into_vector_value();
22502211
let res = builder.build_float_mul(v1, v2, &state.var_name());
22512212
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
22522213
state.push1(res);
22532214
}
22542215
Operator::F32Div | Operator::F64Div => {
22552216
let (v1, v2) = state.pop2()?;
2256-
let v1 = canonicalize_nans(builder, intrinsics, v1);
2257-
let v2 = canonicalize_nans(builder, intrinsics, v2);
22582217
let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
22592218
let res = builder.build_float_div(v1, v2, &state.var_name());
22602219
state.push1(res);
22612220
}
22622221
Operator::F32x4Div => {
22632222
let (v1, v2) = state.pop2()?;
2264-
let v1 = builder.build_bitcast(v1, intrinsics.f32x4_ty, "");
2265-
let v2 = builder.build_bitcast(v2, intrinsics.f32x4_ty, "");
2266-
let v1 = canonicalize_nans(builder, intrinsics, v1);
2267-
let v2 = canonicalize_nans(builder, intrinsics, v2);
2268-
let (v1, v2) = (v1.into_vector_value(), v2.into_vector_value());
2223+
let v1 = builder
2224+
.build_bitcast(v1, intrinsics.f32x4_ty, "")
2225+
.into_vector_value();
2226+
let v2 = builder
2227+
.build_bitcast(v2, intrinsics.f32x4_ty, "")
2228+
.into_vector_value();
22692229
let res = builder.build_float_div(v1, v2, &state.var_name());
22702230
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
22712231
state.push1(res);
22722232
}
22732233
Operator::F64x2Div => {
22742234
let (v1, v2) = state.pop2()?;
2275-
let v1 = builder.build_bitcast(v1, intrinsics.f64x2_ty, "");
2276-
let v2 = builder.build_bitcast(v2, intrinsics.f64x2_ty, "");
2277-
let v1 = canonicalize_nans(builder, intrinsics, v1);
2278-
let v2 = canonicalize_nans(builder, intrinsics, v2);
2279-
let (v1, v2) = (v1.into_vector_value(), v2.into_vector_value());
2235+
let v1 = builder
2236+
.build_bitcast(v1, intrinsics.f64x2_ty, "")
2237+
.into_vector_value();
2238+
let v2 = builder
2239+
.build_bitcast(v2, intrinsics.f64x2_ty, "")
2240+
.into_vector_value();
22802241
let res = builder.build_float_div(v1, v2, &state.var_name());
22812242
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
22822243
state.push1(res);
@@ -3446,14 +3407,12 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
34463407
state.push1(res);
34473408
}
34483409
Operator::F32DemoteF64 => {
3449-
let v1 = state.pop1()?;
3450-
let v1 = canonicalize_nans(builder, intrinsics, v1).into_float_value();
3410+
let v1 = state.pop1()?.into_float_value();
34513411
let res = builder.build_float_trunc(v1, intrinsics.f32_ty, &state.var_name());
34523412
state.push1(res);
34533413
}
34543414
Operator::F64PromoteF32 => {
3455-
let v1 = state.pop1()?;
3456-
let v1 = canonicalize_nans(builder, intrinsics, v1).into_float_value();
3415+
let v1 = state.pop1()?.into_float_value();
34573416
let res = builder.build_float_ext(v1, intrinsics.f64_ty, &state.var_name());
34583417
state.push1(res);
34593418
}

lib/spectests/tests/excludes.txt

+34
Original file line numberDiff line numberDiff line change
@@ -986,6 +986,32 @@ llvm:fail:elem.wast:367 # AssertReturn - result I32(65) ("0x41") does not match
986986
llvm:fail:elem.wast:379 # AssertReturn - Call failed RuntimeError: WebAssembly trap occurred during runtime: incorrect `call_indirect` signature
987987
llvm:fail:elem.wast:380 # AssertReturn - result I32(65) ("0x41") does not match expected I32(69) ("0x45")
988988
llvm:fail:elem.wast:381 # AssertReturn - result I32(66) ("0x42") does not match expected I32(70) ("0x46")
989+
llvm:fail:float_exprs.wast:75 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
990+
llvm:fail:float_exprs.wast:76 # "AssertReturnArithmeticNan" - value is not arithmetic nan F64(NaN)
991+
llvm:fail:float_exprs.wast:106 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
992+
llvm:fail:float_exprs.wast:107 # "AssertReturnArithmeticNan" - value is not arithmetic nan F64(NaN)
993+
llvm:fail:float_exprs.wast:136 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
994+
llvm:fail:float_exprs.wast:137 # "AssertReturnArithmeticNan" - value is not arithmetic nan F64(NaN)
995+
llvm:fail:float_exprs.wast:148 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
996+
llvm:fail:float_exprs.wast:149 # "AssertReturnArithmeticNan" - value is not arithmetic nan F64(NaN)
997+
llvm:fail:float_exprs.wast:160 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
998+
llvm:fail:float_exprs.wast:161 # "AssertReturnArithmeticNan" - value is not arithmetic nan F64(NaN)
999+
llvm:fail:float_exprs.wast:172 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
1000+
llvm:fail:float_exprs.wast:173 # "AssertReturnArithmeticNan" - value is not arithmetic nan F64(NaN)
1001+
llvm:fail:float_exprs.wast:638 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
1002+
llvm:fail:float_exprs.wast:2349 # AssertReturn - result I32(2139095040) ("0x7f800000") does not match expected I32(2143289344) ("0x7fc00000")
1003+
llvm:fail:float_exprs.wast:2350 # AssertReturn - result I32(2139095040) ("0x7f800000") does not match expected I32(2143289344) ("0x7fc00000")
1004+
llvm:fail:float_exprs.wast:2351 # AssertReturn - result I32(2139095040) ("0x7f800000") does not match expected I32(2143289344) ("0x7fc00000")
1005+
llvm:fail:float_exprs.wast:2352 # AssertReturn - result I32(2139095040) ("0x7f800000") does not match expected I32(2143289344) ("0x7fc00000")
1006+
llvm:fail:float_exprs.wast:2353 # AssertReturn - result I32(2139095040) ("0x7f800000") does not match expected I32(2143289344) ("0x7fc00000")
1007+
llvm:fail:float_exprs.wast:2354 # AssertReturn - result I32(2139095040) ("0x7f800000") does not match expected I32(2143289344) ("0x7fc00000")
1008+
llvm:fail:float_exprs.wast:2355 # AssertReturn - result I64(9218868437227405312) ("0x7ff0000000000000") does not match expected I64(9221120237041090560) ("0x7ff8000000000000")
1009+
llvm:fail:float_exprs.wast:2356 # AssertReturn - result I64(9218868437227405312) ("0x7ff0000000000000") does not match expected I64(9221120237041090560) ("0x7ff8000000000000")
1010+
llvm:fail:float_exprs.wast:2357 # AssertReturn - result I64(9218868437227405312) ("0x7ff0000000000000") does not match expected I64(9221120237041090560) ("0x7ff8000000000000")
1011+
llvm:fail:float_exprs.wast:2358 # AssertReturn - result I64(9218868437227405312) ("0x7ff0000000000000") does not match expected I64(9221120237041090560) ("0x7ff8000000000000")
1012+
llvm:fail:float_exprs.wast:2359 # AssertReturn - result I64(9218868437227405312) ("0x7ff0000000000000") does not match expected I64(9221120237041090560) ("0x7ff8000000000000")
1013+
llvm:fail:float_exprs.wast:2360 # AssertReturn - result I64(9218868437227405312) ("0x7ff0000000000000") does not match expected I64(9221120237041090560) ("0x7ff8000000000000")
1014+
llvm:fail:float_exprs.wast:2361 # AssertReturn - result I32(2139095040) ("0x7f800000") does not match expected I32(2143289344) ("0x7fc00000")
9891015
llvm:fail:globals.wast:243 # AssertInvalid - caught panic Any
9901016
llvm:fail:globals.wast:301 # Module - caught panic Any
9911017
llvm:fail:i32.wast:243 # AssertReturn - result I32(79069519) ("0x4b6814f") does not match expected I32(32) ("0x20")
@@ -1116,6 +1142,14 @@ llvm:fail:linking.wast:335 # AssertUnlinkable - caught panic Any
11161142
llvm:fail:linking.wast:387 # AssertReturn - result I32(0) ("0x0") does not match expected I32(104) ("0x68")
11171143
llvm:fail:linking.wast:388 # AssertReturn - Call failed RuntimeError: WebAssembly trap occurred during runtime: incorrect `call_indirect` signature
11181144
llvm:fail:load.wast:201 # AssertReturn - result I32(80568351) ("0x4cd601f") does not match expected I32(32) ("0x20")
1145+
llvm:fail:simd_binaryen.wast:643 # AssertReturn - result V128(87957508823039318797956833756741369856) ("0x422c00007f800000ffc000007fc00000") does not match expected V128(87957508823039318788733461719886594048) ("0x422c00007f8000007fc000007fc00000")
1146+
llvm:fail:simd_binaryen.wast:644 # AssertReturn - result V128(87915970448171040176928589786107609088) ("0x422400007f800000ffc000007fc00000") does not match expected V128(87915970448171040167705217749252833280) ("0x422400007f8000007fc000007fc00000")
1147+
llvm:fail:simd_binaryen.wast:645 # AssertReturn - result V128(88601353633497637423894615301564661760) ("0x42a800007f800000ffc000007fc00000") does not match expected V128(88601353633497637414671243264709885952) ("0x42a800007f8000007fc000007fc00000")
1148+
llvm:fail:simd_binaryen.wast:646 # AssertReturn - result V128(87272125637712721550990808241284317184) ("0x41a800007f800000ffc000007fc00000") does not match expected V128(87272125637712721541767436204429541376) ("0x41a800007f8000007fc000007fc00000")
1149+
llvm:fail:simd_binaryen.wast:658 # AssertReturn - result V128(340240828546070184851567483698175541248) ("0xfff80000000000007ff8000000000000") does not match expected V128(170099645085600953119880179982291435520) ("0x7ff80000000000007ff8000000000000")
1150+
llvm:fail:simd_binaryen.wast:660 # AssertReturn - result V128(340240828546070184851567483698175541248) ("0xfff80000000000007ff8000000000000") does not match expected V128(170099645085600953119880179982291435520) ("0x7ff80000000000007ff8000000000000")
1151+
llvm:fail:simd_binaryen.wast:662 # AssertReturn - result V128(340240828546070184851567483698175541248) ("0xfff80000000000007ff8000000000000") does not match expected V128(170099645085600953119880179982291435520) ("0x7ff80000000000007ff8000000000000")
1152+
llvm:fail:simd_binaryen.wast:664 # AssertReturn - result V128(340240828546070184851567483698175541248) ("0xfff80000000000007ff8000000000000") does not match expected V128(170099645085600953119880179982291435520) ("0x7ff80000000000007ff8000000000000")
11191153
llvm:fail:start.wast:92 # Module - caught panic Any
11201154
llvm:fail:type.wast:3 # Module - caught panic Any
11211155

0 commit comments

Comments
 (0)