Skip to content

Commit be831ac

Browse files
heihertru
authored andcommitted
[LoongArch] Support i128 operands for LSX inline assembly (llvm#211464)
Allow `i128` values to be used with the `f` inline assembly constraint when targeting LSX. Although `i128` is not a legal LSX value type, it naturally maps to a single 128-bit LSX vector register for inline assembly. This enables instructions such as `vadd.q` to operate directly on `__int128` operands without requiring explicit vector types. (cherry picked from commit cad3c95)
1 parent 2a0942d commit be831ac

3 files changed

Lines changed: 38 additions & 0 deletions

File tree

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2
2+
// RUN: %clang_cc1 -triple loongarch64 -emit-llvm -O2 %s -o - | FileCheck %s
3+
4+
// CHECK-LABEL: define dso_local void @test_i128
5+
// CHECK-SAME: (ptr nofree noundef readonly captures(none) [[A:%.*]], ptr nofree noundef readonly captures(none) [[B:%.*]], ptr nofree noundef writeonly captures(none) initializes((0, 16)) [[R:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
6+
// CHECK-NEXT: entry:
7+
// CHECK-NEXT: [[TMP0:%.*]] = load i128, ptr [[A]], align 16, !tbaa [[TBAA6:![0-9]+]]
8+
// CHECK-NEXT: [[TMP1:%.*]] = load i128, ptr [[B]], align 16, !tbaa [[TBAA6]]
9+
// CHECK-NEXT: [[TMP2:%.*]] = tail call i128 asm sideeffect "vadd.q ${0:w}, ${1:w}, ${2:w}", "=f,f,f"(i128 [[TMP0]], i128 [[TMP1]]) #[[ATTR1:[0-9]+]], !srcloc [[META8:![0-9]+]]
10+
// CHECK-NEXT: store i128 [[TMP2]], ptr [[R]], align 16, !tbaa [[TBAA6]]
11+
// CHECK-NEXT: ret void
12+
//
13+
void test_i128(__int128 *a, __int128 *b, __int128 *r) {
14+
asm volatile ("vadd.q %w0, %w1, %w2" : "=f" (*r) : "f" (*a), "f" (*b));
15+
}

llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11327,6 +11327,8 @@ LoongArchTargetLowering::getRegForInlineAsmConstraint(
1132711327
if (Subtarget.hasExtLSX() &&
1132811328
TRI->isTypeLegalForClass(LoongArch::LSX128RegClass, VT))
1132911329
return std::make_pair(0U, &LoongArch::LSX128RegClass);
11330+
if (Subtarget.hasExtLSX() && VT == MVT::i128)
11331+
return std::make_pair(0U, &LoongArch::LSX128RegClass);
1133011332
if (Subtarget.hasExtLASX() &&
1133111333
TRI->isTypeLegalForClass(LoongArch::LASX256RegClass, VT))
1133211334
return std::make_pair(0U, &LoongArch::LASX256RegClass);
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
2+
; RUN: llc --mtriple=loongarch32 -mattr=+32s,+lsx < %s | FileCheck %s
3+
; RUN: llc --mtriple=loongarch64 -mattr=+lsx < %s | FileCheck %s
4+
5+
define void @i128(ptr %a, ptr %b, ptr %r) nounwind {
6+
; CHECK-LABEL: i128:
7+
; CHECK: # %bb.0: # %entry
8+
; CHECK-NEXT: vld $vr0, $a1, 0
9+
; CHECK-NEXT: vld $vr1, $a0, 0
10+
; CHECK-NEXT: #APP
11+
; CHECK-NEXT: vadd.q $vr2, $vr1, $vr0
12+
; CHECK-NEXT: #NO_APP
13+
; CHECK-NEXT: vst $vr2, $a2, 0
14+
; CHECK-NEXT: ret
15+
entry:
16+
%0 = load i128, ptr %a, align 16
17+
%1 = load i128, ptr %b, align 16
18+
%2 = tail call i128 asm sideeffect "vadd.q ${0:w}, ${1:w}, ${2:w}", "=&f,f,f"(i128 %0, i128 %1)
19+
store i128 %2, ptr %r, align 16
20+
ret void
21+
}

0 commit comments

Comments
 (0)