Skip to content
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

Implement comparesf2/comparedf2 intrinsics #222

Merged
merged 7 commits into from
Jan 13, 2018
Merged

Implement comparesf2/comparedf2 intrinsics #222

merged 7 commits into from
Jan 13, 2018

Conversation

whitequark
Copy link
Member

These intrinsics are indeed called on soft-float targets, you can verify this by compiling:

#![no_std]
fn comparesf2(a: f32, b: f32) -> bool { a > b }
fn comparedf2(a: f64, b: f64) -> bool { a > b }

and looking at the disassembly.

Doesn't come with tests because I'm not about to write fourteen of these horrifying build.rs structs by hand, and also because cargo test fails on latest nightly.

E.g. take a look at the assembly output for:

  pub fn comparesf2(a: f32, b: f32) -> bool { a > b }
  pub fn comparedf2(a: f64, b: f64) -> bool { a > b }

which will include calls to __gtsf2 and __gtdf2.
@alexcrichton
Copy link
Member

Thanks! Could at least one test be written? Exercising at least a few of the code paths? Additionally can you gist the error that cargo test has on nightly?

Finally, should these return bool at the ABI level? Could i32 be used for explicitness perhaps?

@alexcrichton
Copy link
Member

Oh and also, do we compile the C version of these intrinsics? If so, can those files be removed from compilation?

@whitequark
Copy link
Member Author

The CI error is an ICE:

error: internal compiler error: /checkout/src/librustc_metadata/cstore_impl.rs:131: get_optimized_mir: missing MIR for `DefId(3/0:10 ~ utest_cortex_m_qemu[aedb]::lang_items[0]::start[0])

The error on nightly (rust version 1.24.0-nightly (77e189cd7 2017-12-28)):

error[E0152]: duplicate lang item found: `i128_add`.
   --> src/macros.rs:292:9
    |
292 | /         pub fn $name( $($argname:  $ty),* ) -> $ret {
293 | |             $($body)*
294 | |         }
    | |_________^
    | 
   ::: src/int/addsub.rs
    |
82  | / u128_lang_items! {
83  | |     #[lang = "i128_add"]
84  | |     pub fn rust_i128_add(a: i128, b: i128) -> i128 {
85  | |         rust_u128_add(a as _, b as _) as _
...   |
123 | |     }
124 | | }
    | |_- in this macro invocation
    |
    = note: first defined in crate `compiler_builtins`.

[lots more of similar errors]

Note that this changes semantics:
    pub extern "C" fn __eqsf2(a: f32, b: f32) -> bool {
        cmp(a, b).to_le_abi() != 0
    }

is not the same as

    pub extern "C" fn __eqsf2(a: f32, b: f32) -> i32 {
        cmp(a, b).to_le_abi()
    }

However, compiler-rt does the latter, so this is actually
an improvement.
@whitequark
Copy link
Member Author

Finally, should these return bool at the ABI level? Could i32 be used for explicitness perhaps?

Good catch, this is actually a divergence from compiler-rt's ABI, since the values are different too (consider the -1 case). I don't think it actually matters but it is a good thing to stay consistent.

Oh and also, do we compile the C version of these intrinsics? If so, can those files be removed from compilation?

Done.

@whitequark
Copy link
Member Author

There's also another test failure I get when running locally, if I comment out the cfg_attr in the u128_lang_items macro:

error: couldn't read "/home/whitequark/Projects/compiler-builtins/target/debug/build/compiler_builtins-ef464c3bcc7b9509/out/udivdi3.rs": No such file or directory (os error 2)
 --> tests/udivdi3.rs:8:1
  |
8 | include!(concat!(env!("OUT_DIR"), "/udivdi3.rs"));
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: Could not compile `compiler_builtins`.
warning: build failed, waiting for other jobs to finish...
error: couldn't read "/home/whitequark/Projects/compiler-builtins/target/debug/build/compiler_builtins-ef464c3bcc7b9509/out/fixunssfti.rs": No such file or directory (os error 2)
 --> tests/fixunssfti.rs:8:1
  |
8 | include!(concat!(env!("OUT_DIR"), "/fixunssfti.rs"));
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

@whitequark
Copy link
Member Author

Ok it looks like the quickcheck style tests only run on cargo test --features gen-tests? And then they succeed on my nightly. I've updated README to mention that.

@whitequark
Copy link
Member Author

Thanks! Could at least one test be written? Exercising at least a few of the code paths?

Excellent catch! There actually was a bug related to signedness handling. I've added tests (not for unord?f2 since that would just be ignored anyway, and not for aliases since that's kinda pointless).

@alexcrichton
Copy link
Member

Thanks! Looks like the failure on arm is relevant?

@whitequark
Copy link
Member Author

Fixed

build.rs Outdated
@@ -5127,8 +5443,6 @@ mod c {
"arm/bswapsi2.S",
"arm/clzdi2.S",
"arm/clzsi2.S",
"arm/comparesf2.S",
"arm/divmodsi4.S",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was this deletion accidental perhaps? (or is the assembly weird like that?)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, oops.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

@alexcrichton
Copy link
Member

@bors: r+

@bors
Copy link
Contributor

bors commented Jan 12, 2018

📌 Commit 205322b has been approved by alexcrichton

@bors
Copy link
Contributor

bors commented Jan 12, 2018

⌛ Testing commit 205322b with merge 1d895cd...

bors added a commit that referenced this pull request Jan 12, 2018
Implement comparesf2/comparedf2 intrinsics

These intrinsics are indeed called on soft-float targets, you can verify this by compiling:
```rust
#![no_std]
fn comparesf2(a: f32, b: f32) -> bool { a > b }
fn comparedf2(a: f64, b: f64) -> bool { a > b }
```
and looking at the disassembly.

Doesn't come with tests because I'm not about to write *fourteen* of these horrifying build.rs structs by hand, and also because `cargo test` fails on latest nightly.
@bors
Copy link
Contributor

bors commented Jan 13, 2018

💥 Test timed out

@alexcrichton
Copy link
Member

@bors: retry

@bors
Copy link
Contributor

bors commented Jan 13, 2018

⌛ Testing commit 205322b with merge 544e517...

bors added a commit that referenced this pull request Jan 13, 2018
Implement comparesf2/comparedf2 intrinsics

These intrinsics are indeed called on soft-float targets, you can verify this by compiling:
```rust
#![no_std]
fn comparesf2(a: f32, b: f32) -> bool { a > b }
fn comparedf2(a: f64, b: f64) -> bool { a > b }
```
and looking at the disassembly.

Doesn't come with tests because I'm not about to write *fourteen* of these horrifying build.rs structs by hand, and also because `cargo test` fails on latest nightly.
@bors
Copy link
Contributor

bors commented Jan 13, 2018

💔 Test failed - status-travis

@alexcrichton
Copy link
Member

Ah right haven't fixed that yet...

@alexcrichton
Copy link
Member

@whitequark mind helping diagnosing a few issues I think are with this PR?

I believe this PR is the cause of this failure, notably on ARM Android we're getting a number of weird floating point results. I tried to correct what I thought were some typos, namely defining our own aeabi aliases (not using compiler-rt's) and fixing the arugments on __gtdf2, but that ended up causing even more regressions locally.

Do you know what's going on here? Do you know if there's an ABI mismatch perhaps with how floats are being passed? Have you tested this locally for the target you're working with?

@whitequark
Copy link
Member Author

Have you tested this locally for the target you're working with?

Yes, for OR1K, it's out-of-tree.

Do you know if there's an ABI mismatch perhaps with how floats are being passed?

Maybe the arguments are swapped? Just like for __aeabi_memcpy and friends.

@alexcrichton
Copy link
Member

Hm ok, it looks like the __aeabi ABI is slightly different not with arguments but at least with return value, I'm testing that out to see if it resolves the problems I found.

I still think though that __gtdf2 needs to be updated, right?

@whitequark
Copy link
Member Author

Yes, that's obviously correct.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants