rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
98.81k stars 12.77k forks source link

target-feature `-hard-float` for powerpc #117347

Open Emilgardis opened 1 year ago

Emilgardis commented 1 year ago

RUSTFLAGS="-C target-feature=-crt-static,-hard-float" cargo +nightly build --release --target powerpc-unknown-linux-musl

gives the warning

warning: unknown feature specified for `-Ctarget-feature`: `hard-float`
  |
  = note: it is still passed through to the codegen backend
  = help: consider filing a feature request

while it should be supported by llvm

rustc +nightly --print=target-features -Z unstable-options --target powerpc-unknown-linux-musl
Features supported by rustc for this target:
    altivec                        - Enable Altivec instructions.
    power10-vector                 - Enable POWER10 vector instructions.
    power8-altivec                 - Enable POWER8 Altivec instructions.
    power8-vector                  - Enable POWER8 vector instructions.
    power9-altivec                 - Enable POWER9 Altivec instructions.
    power9-vector                  - Enable POWER9 vector instructions.
    vsx                            - Enable VSX instructions.
    crt-static                     - Enables C Run-time Libraries to be statically linked.

Code-generation features supported by LLVM for this target:
    64bit                          - Enable 64-bit instructions.
    64bitregs                      - Enable 64-bit registers usage for ppc32 [beta].
    aix                            - AIX OS.
    allow-unaligned-fp-access      - CPU does not trap on unaligned FP access.
    booke                          - Enable Book E instructions.
    bpermd                         - Enable the bpermd instruction.
    cmpb                           - Enable the cmpb instruction.
    crbits                         - Use condition-register bits individually.
    crypto                         - Enable POWER8 Crypto instructions.
    direct-move                    - Enable Power8 direct move instructions.
    e500                           - Enable E500/E500mc instructions.
    efpu2                          - Enable Embedded Floating-Point APU 2 instructions.
    extdiv                         - Enable extended divide instructions.
    fast-MFLR                      - MFLR is a fast instruction.
    fcpsgn                         - Enable the fcpsgn instruction.
    float128                       - Enable the __float128 data type for IEEE-754R Binary128..
    fpcvt                          - Enable fc[ft]* (unsigned and single-precision) and lfiwzx instructions.
    fprnd                          - Enable the fri[mnpz] instructions.
    fpu                            - Enable classic FPU instructions.
    fre                            - Enable the fre instruction.
    fres                           - Enable the fres instruction.
    frsqrte                        - Enable the frsqrte instruction.
    frsqrtes                       - Enable the frsqrtes instruction.
    fsqrt                          - Enable the fsqrt instruction.
    fuse-add-logical               - Target supports Add with Logical Operations fusion.
    fuse-addi-load                 - Power8 Addi-Load fusion.
    fuse-addis-load                - Power8 Addis-Load fusion.
    fuse-arith-add                 - Target supports Arithmetic Operations with Add fusion.
    fuse-back2back                 - Target supports general back to back fusion.
    fuse-cmp                       - Target supports Comparison Operations fusion.
    fuse-logical                   - Target supports Logical Operations fusion.
    fuse-logical-add               - Target supports Logical with Add Operations fusion.
    fuse-sha3                      - Target supports SHA3 assist fusion.
    fuse-store                     - Target supports store clustering.
    fuse-wideimm                   - Target supports Wide-Immediate fusion.
    fuse-zeromove                  - Target supports move to SPR with branch fusion.
    fusion                         - Target supports instruction fusion.
    hard-float                     - Enable floating-point instructions.
    htm                            - Enable Hardware Transactional Memory instructions.
    icbt                           - Enable icbt instruction.
    invariant-function-descriptors - Assume function descriptors are invariant.
    isa-future-instructions        - Enable instructions for Future ISA..
    isa-v206-instructions          - Enable instructions in ISA 2.06..
    isa-v207-instructions          - Enable instructions in ISA 2.07..
    isa-v30-instructions           - Enable instructions in ISA 3.0..
    isa-v31-instructions           - Enable instructions in ISA 3.1..
    isel                           - Enable the isel instruction.
    ldbrx                          - Enable the ldbrx instruction.
    lfiwax                         - Enable the lfiwax instruction.
    longcall                       - Always use indirect calls.
    mfocrf                         - Enable the MFOCRF instruction.
    mma                            - Enable MMA instructions.
    modern-aix-as                  - AIX system assembler is modern enough to support new mnes.
    msync                          - Has only the msync instruction instead of sync.
    paired-vector-memops           - 32Byte load and store instructions.
    partword-atomics               - Enable l[bh]arx and st[bh]cx..
    pcrelative-memops              - Enable PC relative Memory Ops.
    popcntd                        - Enable the popcnt[dw] instructions.
    ppc-postra-sched               - Use PowerPC post-RA scheduling strategy.
    ppc-prera-sched                - Use PowerPC pre-RA scheduling strategy.
    ppc4xx                         - Enable PPC 4xx instructions.
    ppc6xx                         - Enable PPC 6xx instructions.
    predictable-select-expensive   - Prefer likely predicted branches over selects.
    prefix-instrs                  - Enable prefixed instructions.
    privileged                     - Add privileged instructions.
    quadword-atomics               - Enable lqarx and stqcx..
    recipprec                      - Assume higher precision reciprocal estimates.
    rop-protect                    - Add ROP protect.
    secure-plt                     - Enable secure plt mode.
    slow-popcntd                   - Has slow popcnt[dw] instructions.
    spe                            - Enable SPE instructions.
    stfiwx                         - Enable the stfiwx instruction.
    two-const-nr                   - Requires two constant Newton-Raphson computation.
    vectors-use-two-units          - Vectors use two units.

Use +feature to enable a feature, or -feature to disable it.
For example, rustc -C target-cpu=mycpu -C target-feature=+feature1,-feature2

Code-generation features cannot be used in cfg or #[target_feature],
and may be renamed or removed in a future version of LLVM or rustc.

is the error supposed to happen or is this expected?

cc https://github.com/cross-rs/cross/issues/1363

Noratrieb commented 1 year ago

@ecnelises @bzEq you are target maintainers for powerpc64 (which is a different arch but hopefully similar enough) so you may have opinions or know something. our target maintainer documentation is absolutely abysmal so I was not able to find anyone else. lol.

workingjubilee commented 1 year ago

@Emilgardis The warning you see is because not all target features LLVM offers "make sense" in the Rust Cinematic Universe in terms of target features, and also we want to be able to have Rust's target features continue making sense and be something resembling supported if you e.g. use the Cranelift codegen backend (for targets that Cranelift supports). Thus we try to collect them as explicit additions to the compiler, thus we set this warning to prompt people to complain about it (and thus find out which features people actually want suport for).

However, the PowerPC targets should be using hard floats by default, shouldn't they? Why are you manually configuring this feature?

Emilgardis commented 1 year ago

[...] thus we set this warning to prompt people to complain about it (and thus find out which features people actually want suport for).

perfect, makes sense

Seems then that the powerpc-unknown-linux-musl target is wrong, doesn't seem to specify -hard-float

edit: misread your question!

the device we want is a openwrt router that doesn't support hardfloats, MPC8540

workingjubilee commented 1 year ago

Oh, it's a negation! I somehow missed that. That makes sense. I think we'd want to support the total configuration, at least hypothetically, though it implies more exciting adventures in float ABIs.

workingjubilee commented 1 year ago

Wait, that has an e500 core, doesn't it?

The PowerPC e500 is a 32-bit microprocessor core from Freescale Semiconductor. The core is compatible with the older PowerPC Book E specification as well as the Power ISA v.2.03. It has a dual issue, seven-stage pipeline with FPUs (from version 2 onwards)

Not the e500v2, I take it?

Emilgardis commented 1 year ago

@thomas725 can you correct me on the model/arch of the device you're targetting?

RalfJung commented 1 year ago

We shouldn't allow any more float-ABI-affecting target features without a way to ensure ABI compatibility. Softloat and hardfloat mode are not ABI-compatible on many targets since they pass float types in different registers. Is that the case on PowerPC as well? If yes, then either they need to be two different targets, or we need to reject calling functions that take f32/f64 by-val arguments when hardfloat support is absent.

workingjubilee commented 1 year ago

My initial thought was maybe we'd want powerpc (32-bit) targets to default to softfloat.

RalfJung commented 1 year ago

Won't that make extern "C" incompatible with the usual C ABI on that target?

ecnelises commented 1 year ago

Softloat and hardfloat mode are not ABI-compatible on many targets since they pass float types in different registers. Is that the case on PowerPC as well?

Yes. PowerPC hard float uses FPR, while soft float uses GPR.

We shouldn't allow any more float-ABI-affecting target features without a way to ensure ABI compatibility.

IIUC this is to avoid linking objects compiled with different float ABIs (since Rust has no way differentiate them)?


Anyway, making soft float as default for 32-bit ppc is not a good idea.. Even powerpcspe has hard float enabled by default.

RalfJung commented 1 year ago

IIUC this is to avoid linking objects compiled with different float ABIs (since Rust has no way differentiate them)?

Yes. Rust has a way to differentiate them - it's target triples.

ecnelises commented 1 year ago

I know some targets (arm? riscv?) encode float ABI into their triples, which makes sense. BTW encoding float ABI in .gnu_attribute (supported partially by LLVM) may also help in such scenario because linker would refuse linking objects with different attribute value.

thomas725 commented 1 year ago

@Emilgardis it's a TP-Link TL-WDR4900 v1.x featuring a Freescale P1014 MPC85xx SoC. (sorry for the late response)

Emilgardis commented 1 year ago

perfect, that seems to be e500v1 which does have SPE instructions but doesn't feature a FPU. So, I think this issue can be closed as for our specific purpose we should use the target powerpc-unknown-linux-muslspe or possibly powerpc-unknown-linux-musleabispe

for that target, I think

# powerpc-unknown-linux-musleabispe.json
{
    "arch": "powerpc",
    "crt-objects-fallback": "musl",
    "crt-static-default": false,
    "crt-static-respected": true,
    "data-layout": "E-m:e-p:32:32-Fn32-i64:64-n32",
    "dynamic-linking": true,
    "env": "musl",
    "has-rpath": true,
    "has-thread-local": true,
    "linker-flavor": "gnu-cc",
    "llvm-target": "powerpc-unknown-linux-muslspe",
    "max-atomic-width": 32,
    "os": "linux",
    "position-independent-executables": true,
    "pre-link-args": {
        "gnu-cc": [
            "-m32 -mspe"
        ],
    },
    "relro-level": "full",
    "stack-probes": {
        "kind": "inline"
    },
    "supported-split-debuginfo": [
        "packed",
        "unpacked",
        "off"
    ],
    "target-endian": "big",
    "target-family": [
        "unix"
    ],
    "target-mcount": "_mcount",
    "target-pointer-width": "32"
}

is correct. Will have to experiment (I'll update this comment also if a better spec is needed)


However, the question about powerpc-unknown-linux-musl supporting -hardfloat remains, I think the consensus in this issue is that it should be done in another target: powerpc-unknown-linux-muslsf.