[PATCH] Revert "[LoongArch] Support InlineAsm for LSX and LASX"
authorchenli <chenli@loongson.cn>
Mon, 18 Mar 2024 07:16:34 +0000 (15:16 +0800)
committerSylvestre Ledru <sylvestre@debian.org>
Fri, 13 Jun 2025 07:05:47 +0000 (09:05 +0200)
This reverts commit d25c79dc70008b835312e5cc7ef48b199fda3165.

D154931[1] needs to be reverted on LLVM17. As Loongson SIMD Extension(LSX) and
Loongson Advanced SIMD Extension(LASX) are not fully supported on LLVM17,
InlineAsm for LSX and LASX should not be supported as well. Otherwise it leads
to the following issue[2]:
'''
LLVM ERROR: Cannot select: 0x7ffea41a3650: ch = store<(store (s128) into %ir.mask
store52)> 0x7ffea41a35e0, 0x7ffea4196a30, FrameIndex:i64<6>, undef:i64
'''

LSX and LASX are fully supported on LLVM18 and are not supported on LLVM16,
thus only LLVM17 has the problem.

[1] https://reviews.llvm.org/D154931
[2] https://buildd.debian.org/status/fetch.php?pkg=qtdeclarative-opensource-src&arch=loong64&ver=5.15.10%2Bdfsg-2%2Bb1&stamp=1710571569&raw=0

Change-Id: I2bd74a71fe5f0bcadeb04ecf1d63d9f97765e8b5

Gbp-Pq: Name D154931-revert-loong64.patch

13 files changed:
clang/lib/Basic/Targets/LoongArch.cpp
clang/test/CodeGen/LoongArch/lasx/inline-asm-gcc-regs-error.c [deleted file]
clang/test/CodeGen/LoongArch/lasx/inline-asm-gcc-regs.c [deleted file]
clang/test/CodeGen/LoongArch/lasx/inline-asm-operand-modifier.c [deleted file]
clang/test/CodeGen/LoongArch/lsx/inline-asm-gcc-regs-error.c [deleted file]
clang/test/CodeGen/LoongArch/lsx/inline-asm-gcc-regs.c [deleted file]
clang/test/CodeGen/LoongArch/lsx/inline-asm-operand-modifier.c [deleted file]
llvm/lib/Target/LoongArch/LoongArchAsmPrinter.cpp
llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
llvm/test/CodeGen/LoongArch/lasx/inline-asm-operand-modifier.ll [deleted file]
llvm/test/CodeGen/LoongArch/lasx/inline-asm-reg-names.ll [deleted file]
llvm/test/CodeGen/LoongArch/lsx/inline-asm-operand-modifier.ll [deleted file]
llvm/test/CodeGen/LoongArch/lsx/inline-asm-reg-names.ll [deleted file]

index 4448a2ae10a1725e2ca8397200e76f970e58e8fb..96ef29620eb6093eca6758888786c7db6f03dce9 100644 (file)
@@ -33,17 +33,7 @@ ArrayRef<const char *> LoongArchTargetInfo::getGCCRegNames() const {
       "$f19", "$f20", "$f21", "$f22", "$f23", "$f24", "$f25", "$f26", "$f27",
       "$f28", "$f29", "$f30", "$f31",
       // Condition flag registers.
-      "$fcc0", "$fcc1", "$fcc2", "$fcc3", "$fcc4", "$fcc5", "$fcc6", "$fcc7",
-      // 128-bit vector registers.
-      "$vr0", "$vr1", "$vr2", "$vr3", "$vr4", "$vr5", "$vr6", "$vr7", "$vr8",
-      "$vr9", "$vr10", "$vr11", "$vr12", "$vr13", "$vr14", "$vr15", "$vr16",
-      "$vr17", "$vr18", "$vr19", "$vr20", "$vr21", "$vr22", "$vr23", "$vr24",
-      "$vr25", "$vr26", "$vr27", "$vr28", "$vr29", "$vr30", "$vr31",
-      // 256-bit vector registers.
-      "$xr0", "$xr1", "$xr2", "$xr3", "$xr4", "$xr5", "$xr6", "$xr7", "$xr8",
-      "$xr9", "$xr10", "$xr11", "$xr12", "$xr13", "$xr14", "$xr15", "$xr16",
-      "$xr17", "$xr18", "$xr19", "$xr20", "$xr21", "$xr22", "$xr23", "$xr24",
-      "$xr25", "$xr26", "$xr27", "$xr28", "$xr29", "$xr30", "$xr31"};
+      "$fcc0", "$fcc1", "$fcc2", "$fcc3", "$fcc4", "$fcc5", "$fcc6", "$fcc7"};
   return llvm::ArrayRef(GCCRegNames);
 }
 
diff --git a/clang/test/CodeGen/LoongArch/lasx/inline-asm-gcc-regs-error.c b/clang/test/CodeGen/LoongArch/lasx/inline-asm-gcc-regs-error.c
deleted file mode 100644 (file)
index 1fd6025..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-// RUN: not %clang_cc1 -triple loongarch64 -emit-llvm -O2 %s 2>&1 -o - | FileCheck %s
-
-typedef signed char v32i8 __attribute__((vector_size(32), aligned(32)));
-
-void test() {
-// CHECK: :[[#@LINE+1]]:28: error: unknown register name 'xr0' in asm
-    register v32i8 p0 asm ("xr0");
-// CHECK: :[[#@LINE+1]]:29: error: unknown register name '$xr32' in asm
-    register v32i8 p32 asm ("$xr32");
-}
diff --git a/clang/test/CodeGen/LoongArch/lasx/inline-asm-gcc-regs.c b/clang/test/CodeGen/LoongArch/lasx/inline-asm-gcc-regs.c
deleted file mode 100644 (file)
index ed1a966..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --filter "^define |tail call"
-// RUN: %clang_cc1 -triple loongarch64 -emit-llvm -O2 %s -o - | FileCheck %s
-
-typedef signed char v32i8 __attribute__((vector_size(32), aligned(32)));
-
-// CHECK-LABEL: @test_xr0(
-// CHECK:    tail call void asm sideeffect "", "{$xr0}"(<32 x i8> undef) #[[ATTR1:[0-9]+]], !srcloc !2
-//
-void test_xr0() {
-    register v32i8 a asm ("$xr0");
-    asm ("" :: "f"(a));
-}
-
-// CHECK-LABEL: @test_xr7(
-// CHECK:    tail call void asm sideeffect "", "{$xr7}"(<32 x i8> undef) #[[ATTR1]], !srcloc !3
-//
-void test_xr7() {
-    register v32i8 a asm ("$xr7");
-    asm ("" :: "f"(a));
-}
-
-// CHECK-LABEL: @test_xr15(
-// CHECK:    tail call void asm sideeffect "", "{$xr15}"(<32 x i8> undef) #[[ATTR1]], !srcloc !4
-//
-void test_xr15() {
-    register v32i8 a asm ("$xr15");
-    asm ("" :: "f"(a));
-}
-
-// CHECK-LABEL: @test_xr31(
-// CHECK:    tail call void asm sideeffect "", "{$xr31}"(<32 x i8> undef) #[[ATTR1]], !srcloc !5
-//
-void test_xr31() {
-    register v32i8 a asm ("$xr31");
-    asm ("" :: "f"(a));
-}
diff --git a/clang/test/CodeGen/LoongArch/lasx/inline-asm-operand-modifier.c b/clang/test/CodeGen/LoongArch/lasx/inline-asm-operand-modifier.c
deleted file mode 100644 (file)
index a5cc879..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2
-// RUN: %clang_cc1 -triple loongarch64 -emit-llvm -O2 %s -o - | FileCheck %s
-
-typedef long long v4i64 __attribute__ ((vector_size(32), aligned(32)));
-
-// CHECK-LABEL: define dso_local void @test_u
-// CHECK-SAME: () local_unnamed_addr #[[ATTR0:[0-9]+]] {
-// CHECK-NEXT:  entry:
-// CHECK-NEXT:    [[TMP0:%.*]] = tail call <4 x i64> asm sideeffect "xvldi ${0:u}, 1", "=f"() #[[ATTR1:[0-9]+]], !srcloc !2
-// CHECK-NEXT:    ret void
-//
-void test_u() {
-  v4i64 v4i64_r;
-  asm volatile ("xvldi %u0, 1" : "=f" (v4i64_r));
-}
diff --git a/clang/test/CodeGen/LoongArch/lsx/inline-asm-gcc-regs-error.c b/clang/test/CodeGen/LoongArch/lsx/inline-asm-gcc-regs-error.c
deleted file mode 100644 (file)
index 5413230..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-// RUN: not %clang_cc1 -triple loongarch64 -emit-llvm -O2 %s 2>&1 -o - | FileCheck %s
-
-typedef signed char v16i8 __attribute__((vector_size(16), aligned(16)));
-
-void test() {
-// CHECK: :[[#@LINE+1]]:28: error: unknown register name 'vr0' in asm
-    register v16i8 p0 asm ("vr0");
-// CHECK: :[[#@LINE+1]]:29: error: unknown register name '$vr32' in asm
-    register v16i8 p32 asm ("$vr32");
-}
diff --git a/clang/test/CodeGen/LoongArch/lsx/inline-asm-gcc-regs.c b/clang/test/CodeGen/LoongArch/lsx/inline-asm-gcc-regs.c
deleted file mode 100644 (file)
index b05b1c8..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --filter "^define |tail call"
-// RUN: %clang_cc1 -triple loongarch64 -emit-llvm -O2 %s -o - | FileCheck %s
-
-typedef signed char v16i8 __attribute__((vector_size(16), aligned(16)));
-
-// CHECK-LABEL: @test_vr0(
-// CHECK:    tail call void asm sideeffect "", "{$vr0}"(<16 x i8> undef) #[[ATTR1:[0-9]+]], !srcloc !2
-//
-void test_vr0() {
-    register v16i8 a asm ("$vr0");
-    asm ("" :: "f"(a));
-}
-
-// CHECK-LABEL: @test_vr7(
-// CHECK:    tail call void asm sideeffect "", "{$vr7}"(<16 x i8> undef) #[[ATTR1]], !srcloc !3
-//
-void test_vr7() {
-    register v16i8 a asm ("$vr7");
-    asm ("" :: "f"(a));
-}
-
-// CHECK-LABEL: @test_vr15(
-// CHECK:    tail call void asm sideeffect "", "{$vr15}"(<16 x i8> undef) #[[ATTR1]], !srcloc !4
-//
-void test_vr15() {
-    register v16i8 a asm ("$vr15");
-    asm ("" :: "f"(a));
-}
-
-// CHECK-LABEL: @test_vr31(
-// CHECK:    tail call void asm sideeffect "", "{$vr31}"(<16 x i8> undef) #[[ATTR1]], !srcloc !5
-//
-void test_vr31() {
-    register v16i8 a asm ("$vr31");
-    asm ("" :: "f"(a));
-}
diff --git a/clang/test/CodeGen/LoongArch/lsx/inline-asm-operand-modifier.c b/clang/test/CodeGen/LoongArch/lsx/inline-asm-operand-modifier.c
deleted file mode 100644 (file)
index 5e0fae9..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2
-// RUN: %clang_cc1 -triple loongarch64 -emit-llvm -O2 %s -o - | FileCheck %s
-
-typedef long long v2i64 __attribute__ ((vector_size(16), aligned(16)));
-
-// CHECK-LABEL: define dso_local void @test_w
-// CHECK-SAME: () local_unnamed_addr #[[ATTR0:[0-9]+]] {
-// CHECK-NEXT:  entry:
-// CHECK-NEXT:    [[TMP0:%.*]] = tail call <2 x i64> asm sideeffect "vldi ${0:w}, 1", "=f"() #[[ATTR1:[0-9]+]], !srcloc !2
-// CHECK-NEXT:    ret void
-//
-void test_w() {
-  v2i64 v2i64_r;
-  asm volatile ("vldi %w0, 1" : "=f" (v2i64_r));
-}
index 27979a830b10e626420929038aa7186398c68fd5..5cf0673df69a68ea61d934b213cd852323e06844 100644 (file)
@@ -75,20 +75,6 @@ bool LoongArchAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
         return false;
       }
       break;
-    case 'w': // Print LSX registers.
-      if (MO.getReg().id() >= LoongArch::VR0 &&
-          MO.getReg().id() <= LoongArch::VR31)
-        break;
-      // The modifier is 'w' but the operand is not an LSX register; Report an
-      // unknown operand error.
-      return true;
-    case 'u': // Print LASX registers.
-      if (MO.getReg().id() >= LoongArch::XR0 &&
-          MO.getReg().id() <= LoongArch::XR31)
-        break;
-      // The modifier is 'u' but the operand is not an LASX register; Report an
-      // unknown operand error.
-      return true;
       // TODO: handle other extra codes if any.
     }
   }
index db5961fc501a0d838413863cf9b60691d2d13a3a..488e1c7f3a769874fa73b764ce99839982a99183 100644 (file)
@@ -53,14 +53,6 @@ LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM,
     addRegisterClass(MVT::f32, &LoongArch::FPR32RegClass);
   if (Subtarget.hasBasicD())
     addRegisterClass(MVT::f64, &LoongArch::FPR64RegClass);
-  if (Subtarget.hasExtLSX())
-    for (auto VT : {MVT::v4f32, MVT::v2f64, MVT::v16i8, MVT::v8i16, MVT::v4i32,
-                    MVT::v2i64})
-      addRegisterClass(VT, &LoongArch::LSX128RegClass);
-  if (Subtarget.hasExtLASX())
-    for (auto VT : {MVT::v8f32, MVT::v4f64, MVT::v32i8, MVT::v16i16, MVT::v8i32,
-                    MVT::v4i64})
-      addRegisterClass(VT, &LoongArch::LASX256RegClass);
 
   setLoadExtAction({ISD::EXTLOAD, ISD::SEXTLOAD, ISD::ZEXTLOAD}, GRLenVT,
                    MVT::i1, Promote);
@@ -3056,12 +3048,6 @@ LoongArchTargetLowering::getRegForInlineAsmConstraint(
         return std::make_pair(0U, &LoongArch::FPR32RegClass);
       if (Subtarget.hasBasicD() && VT == MVT::f64)
         return std::make_pair(0U, &LoongArch::FPR64RegClass);
-      if (Subtarget.hasExtLSX() &&
-          TRI->isTypeLegalForClass(LoongArch::LSX128RegClass, VT))
-        return std::make_pair(0U, &LoongArch::LSX128RegClass);
-      if (Subtarget.hasExtLASX() &&
-          TRI->isTypeLegalForClass(LoongArch::LASX256RegClass, VT))
-        return std::make_pair(0U, &LoongArch::LASX256RegClass);
       break;
     default:
       break;
@@ -3079,8 +3065,7 @@ LoongArchTargetLowering::getRegForInlineAsmConstraint(
   // decode the usage of register name aliases into their official names. And
   // AFAIK, the not yet upstreamed `rustc` for LoongArch will always use
   // official register names.
-  if (Constraint.startswith("{$r") || Constraint.startswith("{$f") ||
-      Constraint.startswith("{$vr") || Constraint.startswith("{$xr")) {
+  if (Constraint.startswith("{$r") || Constraint.startswith("{$f")) {
     bool IsFP = Constraint[2] == 'f';
     std::pair<StringRef, StringRef> Temp = Constraint.split('$');
     std::pair<unsigned, const TargetRegisterClass *> R;
diff --git a/llvm/test/CodeGen/LoongArch/lasx/inline-asm-operand-modifier.ll b/llvm/test/CodeGen/LoongArch/lasx/inline-asm-operand-modifier.ll
deleted file mode 100644 (file)
index 201e34c..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s
-
-define void @test_u() nounwind {
-; CHECK-LABEL: test_u:
-; CHECK:       # %bb.0: # %entry
-; CHECK-NEXT:    #APP
-; CHECK-NEXT:    xvldi $xr0, 1
-; CHECK-NEXT:    #NO_APP
-; CHECK-NEXT:    ret
-entry:
-  %0 = tail call <4 x i64> asm sideeffect "xvldi ${0:u}, 1", "=f"()
-  ret void
-}
diff --git a/llvm/test/CodeGen/LoongArch/lasx/inline-asm-reg-names.ll b/llvm/test/CodeGen/LoongArch/lasx/inline-asm-reg-names.ll
deleted file mode 100644 (file)
index dd400ec..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
-; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s
-
-define void @register_xr1() nounwind {
-; CHECK-LABEL: register_xr1:
-; CHECK:       # %bb.0: # %entry
-; CHECK-NEXT:    #APP
-; CHECK-NEXT:    xvldi $xr1, 1
-; CHECK-NEXT:    #NO_APP
-; CHECK-NEXT:    ret
-entry:
-  %0 = tail call <4 x i64> asm sideeffect "xvldi ${0:u}, 1", "={$xr1}"()
-  ret void
-}
-
-define void @register_xr7() nounwind {
-; CHECK-LABEL: register_xr7:
-; CHECK:       # %bb.0: # %entry
-; CHECK-NEXT:    #APP
-; CHECK-NEXT:    xvldi $xr7, 1
-; CHECK-NEXT:    #NO_APP
-; CHECK-NEXT:    ret
-entry:
-  %0 = tail call <4 x i64> asm sideeffect "xvldi ${0:u}, 1", "={$xr7}"()
-  ret void
-}
-
-define void @register_xr23() nounwind {
-; CHECK-LABEL: register_xr23:
-; CHECK:       # %bb.0: # %entry
-; CHECK-NEXT:    #APP
-; CHECK-NEXT:    xvldi $xr23, 1
-; CHECK-NEXT:    #NO_APP
-; CHECK-NEXT:    ret
-entry:
-  %0 = tail call <4 x i64> asm sideeffect "xvldi ${0:u}, 1", "={$xr23}"()
-  ret void
-}
-
-;; The lower 64-bit of the vector register '$xr31' is overlapped with
-;; the floating-point register '$f31' ('$fs7'). And '$f31' ('$fs7')
-;; is a callee-saved register which is preserved across calls.
-;; That's why the fst.d and fld.d instructions are emitted.
-define void @register_xr31() nounwind {
-; CHECK-LABEL: register_xr31:
-; CHECK:       # %bb.0: # %entry
-; CHECK-NEXT:    addi.d $sp, $sp, -16
-; CHECK-NEXT:    fst.d $fs7, $sp, 8 # 8-byte Folded Spill
-; CHECK-NEXT:    #APP
-; CHECK-NEXT:    xvldi $xr31, 1
-; CHECK-NEXT:    #NO_APP
-; CHECK-NEXT:    fld.d $fs7, $sp, 8 # 8-byte Folded Reload
-; CHECK-NEXT:    addi.d $sp, $sp, 16
-; CHECK-NEXT:    ret
-entry:
-  %0 = tail call <4 x i64> asm sideeffect "xvldi ${0:u}, 1", "={$xr31}"()
-  ret void
-}
diff --git a/llvm/test/CodeGen/LoongArch/lsx/inline-asm-operand-modifier.ll b/llvm/test/CodeGen/LoongArch/lsx/inline-asm-operand-modifier.ll
deleted file mode 100644 (file)
index c46e624..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s
-
-define void @test_w() nounwind {
-; CHECK-LABEL: test_w:
-; CHECK:       # %bb.0: # %entry
-; CHECK-NEXT:    #APP
-; CHECK-NEXT:    vldi $vr0, 1
-; CHECK-NEXT:    #NO_APP
-; CHECK-NEXT:    ret
-entry:
-  %0 = tail call <2 x i64> asm sideeffect "vldi ${0:w}, 1", "=f"()
-  ret void
-}
diff --git a/llvm/test/CodeGen/LoongArch/lsx/inline-asm-reg-names.ll b/llvm/test/CodeGen/LoongArch/lsx/inline-asm-reg-names.ll
deleted file mode 100644 (file)
index ceea362..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
-; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s
-
-define void @register_vr1() nounwind {
-; CHECK-LABEL: register_vr1:
-; CHECK:       # %bb.0: # %entry
-; CHECK-NEXT:    #APP
-; CHECK-NEXT:    vldi $vr1, 1
-; CHECK-NEXT:    #NO_APP
-; CHECK-NEXT:    ret
-entry:
-  %0 = tail call <2 x i64> asm sideeffect "vldi ${0:w}, 1", "={$vr1}"()
-  ret void
-}
-
-define void @register_vr7() nounwind {
-; CHECK-LABEL: register_vr7:
-; CHECK:       # %bb.0: # %entry
-; CHECK-NEXT:    #APP
-; CHECK-NEXT:    vldi $vr7, 1
-; CHECK-NEXT:    #NO_APP
-; CHECK-NEXT:    ret
-entry:
-  %0 = tail call <2 x i64> asm sideeffect "vldi ${0:w}, 1", "={$vr7}"()
-  ret void
-}
-
-define void @register_vr23() nounwind {
-; CHECK-LABEL: register_vr23:
-; CHECK:       # %bb.0: # %entry
-; CHECK-NEXT:    #APP
-; CHECK-NEXT:    vldi $vr23, 1
-; CHECK-NEXT:    #NO_APP
-; CHECK-NEXT:    ret
-entry:
-  %0 = tail call <2 x i64> asm sideeffect "vldi ${0:w}, 1", "={$vr23}"()
-  ret void
-}
-
-;; The lower half of the vector register '$vr31' is overlapped with
-;; the floating-point register '$f31'. And '$f31' is a callee-saved
-;; register which is preserved across calls. That's why the
-;; fst.d and fld.d instructions are emitted.
-define void @register_vr31() nounwind {
-; CHECK-LABEL: register_vr31:
-; CHECK:       # %bb.0: # %entry
-; CHECK-NEXT:    addi.d $sp, $sp, -16
-; CHECK-NEXT:    fst.d $fs7, $sp, 8 # 8-byte Folded Spill
-; CHECK-NEXT:    #APP
-; CHECK-NEXT:    vldi $vr31, 1
-; CHECK-NEXT:    #NO_APP
-; CHECK-NEXT:    fld.d $fs7, $sp, 8 # 8-byte Folded Reload
-; CHECK-NEXT:    addi.d $sp, $sp, 16
-; CHECK-NEXT:    ret
-entry:
-  %0 = tail call <2 x i64> asm sideeffect "vldi ${0:w}, 1", "={$vr31}"()
-  ret void
-}