rust-lang / rust

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

[LoongArch] Unexpected conditional compilation directive for `target_feature` #133276

Open heiher opened 1 day ago

heiher commented 1 day ago

I tried this code:

#![feature(stdarch_loongarch)]
use std::arch::loongarch64::*;

#[cfg(target_feature = "lasx")]
pub unsafe fn simd(s: i32) -> i32 {
    lasx_xvpickve2gr_w::<0>(lasx_xvreplgr2vr_w(s))
}
rustc --crate-type lib --emit llvm-ir -o lasx.ll lasx.rs

I expected to see this happen:

The simd function was not compiled due to the missing lasx feature.

Instead, this happened:

The simd function was generated.

Meta

rustc --version --verbose:

rustc 1.84.0-nightly (3fee0f12e 2024-11-20)
binary: rustc
commit-hash: 3fee0f12e4f595948f8f54f57c8b7a7a58127124
commit-date: 2024-11-20
host: loongarch64-unknown-linux-gnu
release: 1.84.0-nightly
LLVM version: 19.1.3

rustc -Z unstable-options --print target-spec-json:

{
  "arch": "loongarch64",
  "code-model": "medium",
  "crt-objects-fallback": "false",
  "crt-static-respected": true,
  "data-layout": "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128",
  "direct-access-external-data": false,
  "dynamic-linking": true,
  "env": "gnu",
  "features": "+f,+d,+lsx",
  "has-rpath": true,
  "has-thread-local": true,
  "linker-flavor": "gnu-cc",
  "llvm-abiname": "lp64d",
  "llvm-target": "loongarch64-unknown-linux-gnu",
  "max-atomic-width": 64,
  "metadata": {
    "description": "LoongArch64 Linux, LP64D ABI (kernel 5.19, glibc 2.36)",
    "host_tools": true,
    "std": true,
    "tier": 2
  },
  "os": "linux",
  "position-independent-executables": true,
  "relro-level": "full",
  "supported-sanitizers": [
    "address",
    "leak",
    "memory",
    "thread",
    "cfi"
  ],
  "supported-split-debuginfo": [
    "packed",
    "unpacked",
    "off"
  ],
  "supports-xray": true,
  "target-family": [
    "unix"
  ],
  "target-pointer-width": "64"
}
heiher commented 1 day ago

Although the lasx feature is not enabled in the LoongArch target specification, the CPU defaults to generic. This is replaced in the LLVM backend with the la464 processor model, which includes the lasx feature.

https://github.com/llvm/llvm-project/tree/llvmorg-19.1.4/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCTargetDesc.cpp#L55-L60

static MCSubtargetInfo *
createLoongArchMCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) {
  if (CPU.empty() || CPU == "generic")
    CPU = TT.isArch64Bit() ? "la464" : "generic-la32";
  return createLoongArchMCSubtargetInfoImpl(TT, CPU, /*TuneCPU*/ CPU, FS);
}

The issue was addressed in the llvm main branch by llvm/llvm-project#114922. I'll request a backport.