Description of problem: test run-pass/simd-intrinsic-generic-cast.rs from rust internal testsuite fails on both rhel-7.5 and rhel-alt-7.5 in ppc64le. The testcase runs successfully in other archs. Version-Release number of selected component (if applicable): rust-toolset-7-rust-1.24.0-1.el7 How reproducible: 100% Steps to Reproduce: 1. rpmbuild --rebuild rust-toolset-7-rust-1.24.0-1.el7.src.rpm Actual results: (...) test [run-pass] run-pass/simd-intrinsic-generic-cast.rs ... FAILED (...) ---- [run-pass] run-pass/simd-intrinsic-generic-cast.rs stdout ---- error: test run failed! status: exit code: 101 command: "/root/rpmbuild/BUILD/rustc-1.24.0-src/build/powerpc64le-unknown-linux-gnu/test/run-pass/simd-intrinsic-generic-cast.stage2-powerpc64le-unknown-linux-gnu" stdout: ------------------------------------------ ------------------------------------------ stderr: ------------------------------------------ thread 'main' panicked at 'f64 -> i32 (i32x4(-1234567, 12345678, -123456792, 1234567936) != i32x4(-1234567, 12345678, -123456789, 1234567890))', /root/rpmbuild/BUILD/rustc-1.24.0-src/src/test/run-pass/simd-intrinsic-generic-cast.rs:128:5 note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace. stack backtrace: 0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace at libstd/sys/unix/backtrace/tracing/gcc_s.rs:49 1: std::sys_common::backtrace::print at libstd/sys_common/backtrace.rs:68 at libstd/sys_common/backtrace.rs:57 2: std::panicking::default_hook::{{closure}} at libstd/panicking.rs:381 3: std::panicking::default_hook at libstd/panicking.rs:397 4: std::panicking::rust_panic_with_hook at libstd/panicking.rs:577 5: std::panicking::begin_panic at libstd/panicking.rs:538 6: std::panicking::begin_panic_fmt at libstd/panicking.rs:522 7: simd_intrinsic_generic_cast::main 8: std::rt::lang_start::{{closure}} ------------------------------------------ thread '[run-pass] run-pass/simd-intrinsic-generic-cast.rs' panicked at 'explicit panic', tools/compiletest/src/runtest.rs:2788:9 note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace. stack backtrace: 0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace at libstd/sys/unix/backtrace/tracing/gcc_s.rs:49 1: std::sys_common::backtrace::print at libstd/sys_common/backtrace.rs:68 at libstd/sys_common/backtrace.rs:57 2: std::panicking::default_hook::{{closure}} at libstd/panicking.rs:381 3: std::panicking::default_hook at libstd/panicking.rs:391 4: std::panicking::rust_panic_with_hook at libstd/panicking.rs:577 5: std::panicking::begin_panic 6: compiletest::runtest::ProcRes::fatal 7: compiletest::runtest::TestCx::fatal_proc_rec 8: compiletest::runtest::TestCx::run_rpass_test 9: compiletest::runtest::TestCx::run_revision 10: compiletest::runtest::run 11: <F as alloc::boxed::FnBox<A>>::call_box (...)
Note, the `repr(simd)` used in this test is still an unstable compiler feature, so there's no user impact here yet.
Created attachment 1470920 [details] Reduced test case Reduced test case. This requires the RUSTC_BOOTSTRAP=1 environment variable, since it is using unstable features.
Tom, I think this may be a codegen error in LLVM -- can you take a look? Running the attached test case passes on other arches, but ppc64le outputs: thread 'main' panicked at 'assertion failed: `(left == right)` left: `i32x4(-1234567, 12345678, -123456789, 1234567890)`, right: `i32x4(-1234567, 12345678, -123456792, 1234567936)`', simd-cast.rs:36:5 This test is casting from simd f64x4 to i32x4. The "left" line has the values we expect, and "right" is what we got from the simd cast. Note that 1234567890 = 0x499602d2, and 1234567936 = 0x49960300. This looks exactly like the mantissa rounding you'd get from f64->f32->i32, versus the direct f64->i32 conversion we want that shouldn't lose bits. Here's the LLVM-IR and asm for the function which does the actual simd cast: ; simd_cast::cast ; Function Attrs: uwtable define internal void @_ZN9simd_cast4cast17h5261798b19538724E(<4 x i32>* noalias nocapture sret dereferenceable(16), <4 x double>* noalias nocapture dereferenceable(32) %v) unnamed_addr #0 { start: %1 = load <4 x double>, <4 x double>* %v, align 32 %2 = fptosi <4 x double> %1 to <4 x i32> store <4 x i32> %2, <4 x i32>* %0, align 16 br label %bb1 bb1: ; preds = %start ret void } .section .text._ZN9simd_cast4cast17h5261798b19538724E,"ax",@progbits .p2align 4 .type _ZN9simd_cast4cast17h5261798b19538724E,@function _ZN9simd_cast4cast17h5261798b19538724E: .Lfunc_begin14: .cfi_startproc li 5, 16 lxvd2x 0, 4, 5 xxswapd 0, 0 lxvd2x 1, 0, 4 xxswapd 1, 1 xxmrgld 2, 0, 1 xvcvdpsp 34, 2 xxmrghd 0, 0, 1 xvcvdpsp 35, 0 vmrgew 2, 3, 2 xvcvspsxws 34, 34 stvx 2, 0, 3 blr .long 0 .quad 0 .Lfunc_end14: .size _ZN9simd_cast4cast17h5261798b19538724E, .Lfunc_end14-.Lfunc_begin14 .cfi_endproc The IR is a simple fptosi, but in the asm I notice: xvcvdpsp = VSX Vector DP-SP Conversion xvcvspsxws = VSX Vector Convert Single-Precision to Integer which is pretty much the f64->f32->i32 conversion that I suspected.
It looks like this is not actually limited to little-endian -- it's just that ppc64le has a higher baseline target-cpu for POWER8, which enables VSX. If I run the test compiled with -Ctarget-feature=-vsx, then it passes! Using -Ctarget-cpu=pwr8 on big-endian ppc64, I do get similar asm: .section .text._ZN9simd_cast4cast17h5261798b19538724E,"ax",@progbits .p2align 4 .type _ZN9simd_cast4cast17h5261798b19538724E,@function .section .opd,"aw",@progbits _ZN9simd_cast4cast17h5261798b19538724E: .p2align 3 .quad .Lfunc_begin14 .quad .TOC.@tocbase .quad 0 .section .text._ZN9simd_cast4cast17h5261798b19538724E,"ax",@progbits .Lfunc_begin14: .cfi_startproc li 5, 16 lxvd2x 0, 4, 5 lxvd2x 1, 0, 4 xxmrgld 2, 1, 0 xvcvdpsp 34, 2 xxmrghd 0, 1, 0 xvcvdpsp 35, 0 vmrgew 2, 3, 2 xvcvspsxws 0, 34 stxvw4x 0, 0, 3 blr .long 0 .quad 0 .Lfunc_end14: .size _ZN9simd_cast4cast17h5261798b19538724E, .Lfunc_end14-.Lfunc_begin14 .cfi_endproc
Since the problem described in this bug report should be resolved in a recent advisory, it has been closed with a resolution of ERRATA. For information on the advisory, and where to find the updated files, follow the link below. If the solution does not work for you, open a new bug report. https://access.redhat.com/errata/RHEA-2018:3584