From 0ee99cf240053bc6a73a70922a3c156343555f4b Mon Sep 17 00:00:00 2001
From: WANG Rui <wangrui@loongson.cn>
Date: Mon, 17 Mar 2025 15:03:33 +0800
Subject: [PATCH] rustc_target: Add target feature constraints for LoongArch

Part of https://github.com/rust-lang/rust/issues/116344
---
 compiler/rustc_target/src/target_features.rs | 22 ++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs
index a32b42a6fe333..a96caf227f747 100644
--- a/compiler/rustc_target/src/target_features.rs
+++ b/compiler/rustc_target/src/target_features.rs
@@ -923,6 +923,28 @@ impl Target {
                     _ => unreachable!(),
                 }
             }
+            "loongarch64" => {
+                // LoongArch handles ABI in a very sane way, being fully explicit via `llvm_abiname`
+                // about what the intended ABI is.
+                match &*self.llvm_abiname {
+                    "ilp32d" | "lp64d" => {
+                        // Requires d (which implies f), incompatible with nothing.
+                        FeatureConstraints { required: &["d"], incompatible: &[] }
+                    }
+                    "ilp32f" | "lp64f" => {
+                        // Requires f, incompatible with nothing.
+                        FeatureConstraints { required: &["f"], incompatible: &[] }
+                    }
+                    "ilp32s" | "lp64s" => {
+                        // The soft-float ABI does not require any features and is also not
+                        // incompatible with any features. Rust targets explicitly specify the
+                        // LLVM ABI names, which allows for enabling hard-float support even on
+                        // soft-float targets, and ensures that the ABI behavior is as expected.
+                        NOTHING
+                    }
+                    _ => unreachable!(),
+                }
+            }
             _ => NOTHING,
         }
     }