Discussion:
[rust-dev] SSE problem
silvio
2014-09-20 21:20:50 UTC
Permalink
Hello

I've been trying to replicate an SSE trick from a c program in rust and
come up with some strange behavior. It seems work for --opt-level 0,1
but gives the wrong result on 2,3. I used the !asm instruction to
execute assembly commands.

I'm not sure if this is a bug or just me not using asm! correctly.

The most condensed version that still produces the bug is appended.

on opt 0,1 I get the correct answer 2
on opt 2,3 I get the wrong answer 0

Silvio
-------------- next part --------------
#![feature(asm)]
use std::simd::f32x4;
use std::simd::f64x2;

fn main() {

let one2 = f64x2(1f64,1f64);
println!("one2 1: {}", one2);
let shift = mm_convert_f32x4_f64x2(mm_convert_f64x2_f32x4(one2))+one2;


let f64x2(res1, _) = shift;
println!("res: {}", res1);
}

#[cfg(target_arch = "x86")] #[cfg(target_arch = "x86_64")]
fn mm_convert_f32x4_f64x2(a: f32x4) -> f64x2 {
let mut ret : f64x2 = unsafe {std::mem::uninitialized()};
unsafe {
asm!("cvtps2pd $0, $1"
: "=x"(ret)
: "x"(a)
);
}
ret
}

#[cfg(target_arch = "x86")] #[cfg(target_arch = "x86_64")]
fn mm_convert_f64x2_f32x4(a: f64x2) -> f32x4 {
let mut ret : f32x4 = unsafe {std::mem::uninitialized()};
unsafe {
asm!("cvtpd2ps $0, $1"
: "=x"(ret)
: "x"(a)
);
}
ret
}

#[cfg(target_arch = "x86")] #[cfg(target_arch = "x86_64")]
fn mm_sqrt_reciprocal_f32x4(a: f32x4) -> f32x4 {
let mut ret : f32x4 = unsafe {std::mem::uninitialized()};
unsafe {
asm!("rsqrtps $0, $1"
: "=x"(ret)
: "x"(a)
);
}
ret
}
Peter Marheine
2014-09-20 22:05:10 UTC
Permalink
What kind of "strange behavior" are you getting? Segfaults, wrong
results, or something else entirely?

Your code looks okay to me at a glance, but I'd be inclined to think
it's still a problem on your end. asm! mostly plumbs down to LLVM for
expansion, and the odds of LLVM having a bug there are lower than
those of you having a bug.

Have you looked at the generated assembly to see what it's doing
(--emit asm)? I'd guess there's a problem with the constraints you're
specifying, which will probably be pretty obvious. You'll probably
see wrong values going into the inline assembly block or the
computation clobbering a register used soon afterward.
Post by silvio
Hello
I've been trying to replicate an SSE trick from a c program in rust and
come up with some strange behavior. It seems work for --opt-level 0,1
but gives the wrong result on 2,3. I used the !asm instruction to
execute assembly commands.
I'm not sure if this is a bug or just me not using asm! correctly.
The most condensed version that still produces the bug is appended.
on opt 0,1 I get the correct answer 2
on opt 2,3 I get the wrong answer 0
Silvio
_______________________________________________
Rust-dev mailing list
Rust-dev at mozilla.org
https://mail.mozilla.org/listinfo/rust-dev
--
Peter Marheine
Don't Panic
silvio
2014-09-21 00:18:41 UTC
Permalink
Post by Peter Marheine
What kind of "strange behavior" are you getting? Segfaults, wrong
results, or something else entirely?
ok I found out I had the source dest order reversed, because i was
leafing through the intel manual. That was really annoying I never heard
of that.

If I added some sse functions to f32x4, ... using this inline style.
Would this be likely be merged or are there plans to deal with simd in
some other way? Is there some code already around?

Also is there also a way of inlineing llvm instructions? Because they
already have some already abstracted simd operations.

Silvio

Loading...