Skip to content

[AArch64][GlobalISel] Use integer types for inline assembly lowering#212214

Open
davemgreen wants to merge 1 commit into
llvm:mainfrom
davemgreen:gh-gi-inlineasmty
Open

[AArch64][GlobalISel] Use integer types for inline assembly lowering#212214
davemgreen wants to merge 1 commit into
llvm:mainfrom
davemgreen:gh-gi-inlineasmty

Conversation

@davemgreen

Copy link
Copy Markdown
Contributor

If we need to generate a trunc then we can use an integer type for the lowering.

If we need to generate a trunc then we can use an integer type for the
lowering.
@llvmorg-github-actions

llvmorg-github-actions Bot commented Jul 27, 2026

Copy link
Copy Markdown

@llvm/pr-subscribers-backend-aarch64

@llvm/pr-subscribers-llvm-globalisel

Author: David Green (davemgreen)

Changes

If we need to generate a trunc then we can use an integer type for the lowering.


Full diff: https://github.com/llvm/llvm-project/pull/212214.diff

2 Files Affected:

  • (modified) llvm/lib/CodeGen/GlobalISel/InlineAsmLowering.cpp (+3-5)
  • (modified) llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-inline-asm.ll (+14-14)
diff --git a/llvm/lib/CodeGen/GlobalISel/InlineAsmLowering.cpp b/llvm/lib/CodeGen/GlobalISel/InlineAsmLowering.cpp
index b5bbcc193b6b7..07531d08484a8 100644
--- a/llvm/lib/CodeGen/GlobalISel/InlineAsmLowering.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/InlineAsmLowering.cpp
@@ -219,7 +219,7 @@ static bool buildAnyextOrCopy(Register Dst, Register Src,
                            "destination register class\n");
       return false;
     }
-    Src = MIRBuilder.buildAnyExt(LLT::scalar(DstSize), Src).getReg(0);
+    Src = MIRBuilder.buildAnyExt(LLT::integer(DstSize), Src).getReg(0);
   }
 
   MIRBuilder.buildCopy(Dst, Src);
@@ -636,11 +636,9 @@ bool InlineAsmLowering::lowerInlineAsm(
       if (ResTy.isScalar() && ResTy.getSizeInBits() < SrcSize) {
         // First copy the non-typed virtual register into a generic virtual
         // register
-        Register Tmp1Reg =
-            MRI->createGenericVirtualRegister(LLT::scalar(SrcSize));
-        MIRBuilder.buildCopy(Tmp1Reg, SrcReg);
+        auto Copy = MIRBuilder.buildCopy(LLT::integer(SrcSize), SrcReg);
         // Need to truncate the result of the register
-        MIRBuilder.buildTrunc(ResRegs[i], Tmp1Reg);
+        MIRBuilder.buildTrunc(ResRegs[i], Copy);
       } else if (ResTy.getSizeInBits() == SrcSize) {
         MIRBuilder.buildCopy(ResRegs[i], SrcReg);
       } else {
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-inline-asm.ll b/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-inline-asm.ll
index d627e11f4aa0c..bc40b2e758358 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-inline-asm.ll
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-inline-asm.ll
@@ -110,8 +110,8 @@ define i32 @test_specific_register_output_trunc() nounwind ssp {
   ; CHECK-LABEL: name: test_specific_register_output_trunc
   ; CHECK: bb.1.entry:
   ; CHECK-NEXT:   INLINEASM &"mov ${0:w}, 7", attdialect, regdef, implicit-def $x0
-  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:_(s64) = COPY $x0
-  ; CHECK-NEXT:   [[TRUNC:%[0-9]+]]:_(i32) = G_TRUNC [[COPY]](s64)
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:_(i64) = COPY $x0
+  ; CHECK-NEXT:   [[TRUNC:%[0-9]+]]:_(i32) = G_TRUNC [[COPY]](i64)
   ; CHECK-NEXT:   $w0 = COPY [[TRUNC]](i32)
   ; CHECK-NEXT:   RET_ReallyLR implicit $w0
 entry:
@@ -126,8 +126,8 @@ define zeroext i8 @test_register_output_trunc(ptr %src) nounwind {
   ; CHECK-NEXT: {{  $}}
   ; CHECK-NEXT:   [[COPY:%[0-9]+]]:_(p0) = COPY $x0
   ; CHECK-NEXT:   INLINEASM &"mov ${0:w}, 32", attdialect, regdef:GPR32common, def %1
-  ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:_(s32) = COPY %1
-  ; CHECK-NEXT:   [[TRUNC:%[0-9]+]]:_(i8) = G_TRUNC [[COPY1]](s32)
+  ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:_(i32) = COPY %1
+  ; CHECK-NEXT:   [[TRUNC:%[0-9]+]]:_(i8) = G_TRUNC [[COPY1]](i32)
   ; CHECK-NEXT:   [[ZEXT:%[0-9]+]]:_(i32) = G_ZEXT [[TRUNC]](i8)
   ; CHECK-NEXT:   $w0 = COPY [[ZEXT]](i32)
   ; CHECK-NEXT:   RET_ReallyLR implicit $w0
@@ -210,8 +210,8 @@ define zeroext i8 @test_input_register(ptr %src) nounwind {
   ; CHECK-NEXT:   [[COPY:%[0-9]+]]:_(p0) = COPY $x0
   ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:gpr64common = COPY [[COPY]](p0)
   ; CHECK-NEXT:   INLINEASM &"ldtrb ${0:w}, [$1]", attdialect, regdef:GPR32common, def %1, reguse:GPR64common, [[COPY1]]
-  ; CHECK-NEXT:   [[COPY2:%[0-9]+]]:_(s32) = COPY %1
-  ; CHECK-NEXT:   [[TRUNC:%[0-9]+]]:_(i8) = G_TRUNC [[COPY2]](s32)
+  ; CHECK-NEXT:   [[COPY2:%[0-9]+]]:_(i32) = COPY %1
+  ; CHECK-NEXT:   [[TRUNC:%[0-9]+]]:_(i8) = G_TRUNC [[COPY2]](i32)
   ; CHECK-NEXT:   [[ZEXT:%[0-9]+]]:_(i32) = G_ZEXT [[TRUNC]](i8)
   ; CHECK-NEXT:   $w0 = COPY [[ZEXT]](i32)
   ; CHECK-NEXT:   RET_ReallyLR implicit $w0
@@ -238,11 +238,11 @@ define i16 @test_anyext_input() {
   ; CHECK-LABEL: name: test_anyext_input
   ; CHECK: bb.1 (%ir-block.0):
   ; CHECK-NEXT:   [[C:%[0-9]+]]:_(i16) = G_CONSTANT i16 1
-  ; CHECK-NEXT:   [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[C]](i16)
-  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gpr32common = COPY [[ANYEXT]](s32)
+  ; CHECK-NEXT:   [[ANYEXT:%[0-9]+]]:_(i32) = G_ANYEXT [[C]](i16)
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gpr32common = COPY [[ANYEXT]](i32)
   ; CHECK-NEXT:   INLINEASM &"", sideeffect attdialect, regdef:GPR32common, def %0, reguse:GPR32common, [[COPY]]
-  ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:_(s32) = COPY %0
-  ; CHECK-NEXT:   [[TRUNC:%[0-9]+]]:_(i16) = G_TRUNC [[COPY1]](s32)
+  ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:_(i32) = COPY %0
+  ; CHECK-NEXT:   [[TRUNC:%[0-9]+]]:_(i16) = G_TRUNC [[COPY1]](i32)
   ; CHECK-NEXT:   [[ANYEXT1:%[0-9]+]]:_(i32) = G_ANYEXT [[TRUNC]](i16)
   ; CHECK-NEXT:   $w0 = COPY [[ANYEXT1]](i32)
   ; CHECK-NEXT:   RET_ReallyLR implicit $w0
@@ -254,11 +254,11 @@ define i16 @test_anyext_input_with_matching_constraint() {
   ; CHECK-LABEL: name: test_anyext_input_with_matching_constraint
   ; CHECK: bb.1 (%ir-block.0):
   ; CHECK-NEXT:   [[C:%[0-9]+]]:_(i16) = G_CONSTANT i16 1
-  ; CHECK-NEXT:   [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[C]](i16)
-  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gpr32common = COPY [[ANYEXT]](s32)
+  ; CHECK-NEXT:   [[ANYEXT:%[0-9]+]]:_(i32) = G_ANYEXT [[C]](i16)
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gpr32common = COPY [[ANYEXT]](i32)
   ; CHECK-NEXT:   INLINEASM &"", sideeffect attdialect, regdef:GPR32common, def %0, reguse tiedto:$0, [[COPY]](tied-def 3)
-  ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:_(s32) = COPY %0
-  ; CHECK-NEXT:   [[TRUNC:%[0-9]+]]:_(i16) = G_TRUNC [[COPY1]](s32)
+  ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:_(i32) = COPY %0
+  ; CHECK-NEXT:   [[TRUNC:%[0-9]+]]:_(i16) = G_TRUNC [[COPY1]](i32)
   ; CHECK-NEXT:   [[ANYEXT1:%[0-9]+]]:_(i32) = G_ANYEXT [[TRUNC]](i16)
   ; CHECK-NEXT:   $w0 = COPY [[ANYEXT1]](i32)
   ; CHECK-NEXT:   RET_ReallyLR implicit $w0

@cofibrant

Copy link
Copy Markdown
Member

I was trying to understand this, but I couldn't really follow. Is there an invariant that asserts that the out register is not an FP register? Is there never a situation where we might want a G_FPTRUNC?

@arsenm

arsenm commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

I was trying to understand this, but I couldn't really follow. Is there an invariant that asserts that the out register is not an FP register? Is there never a situation where we might want a G_FPTRUNC?

Those would be a different path, but ideally there wouldn't be implicit FP casts inserted anywhere

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants