Skip to content

Conversation

nikic
Copy link
Contributor

@nikic nikic commented Sep 3, 2025

This hook replaces inline asm with LLVM intrinsics. It was intended to match inline assembly implementations of bswap in libc headers and replace them more optimizable implementations.

At this point, it has outlived its usefulness (see #156571 (comment)), as libc implementations no longer use inline assembly for this purpose.

Additionally, it breaks the "black box" property of inline assembly, which some languages like Rust would like to guarantee.

Fixes #156571.

This hook replaces inline asm with LLVM intrinsics. It was intended
to match inline assembly implementations of bswap and similar in
libc headers and replace them more optimizable implementations.

At this point, it has outlived its usefulness (see llvm#156571 (comment)), as libc implementations no longer use inline assembly for this purpose.

Additionally, it breaks the "black box" property of inline assembly,
which some languages like Rust would like to guarantee.

Fixes llvm#156571.
; CHECK-NEXT: retq
%asmtmp = tail call i32 asm "bswapl ${0:q}", "=r,0,~{dirflag},~{fpsr},~{flags}"(i32 %x) nounwind
%asmtmp = tail call i32 asm "bswapl ${0:k}", "=r,0,~{dirflag},~{fpsr},~{flags}"(i32 %x) nounwind
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The transform hid a bug in the inline asm string. This was using the wrong register class.

@llvmbot
Copy link
Member

llvmbot commented Sep 3, 2025

@llvm/pr-subscribers-backend-x86

@llvm/pr-subscribers-backend-arm

Author: Nikita Popov (nikic)

Changes

This hook replaces inline asm with LLVM intrinsics. It was intended to match inline assembly implementations of bswap in libc headers and replace them more optimizable implementations.

At this point, it has outlived its usefulness (see #156571 (comment)), as libc implementations no longer use inline assembly for this purpose.

Additionally, it breaks the "black box" property of inline assembly, which some languages like Rust would like to guarantee.

Fixes #156571.


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

10 Files Affected:

  • (modified) llvm/include/llvm/CodeGen/TargetLowering.h (-8)
  • (modified) llvm/lib/CodeGen/CodeGenPrepare.cpp (+3-16)
  • (modified) llvm/lib/Target/ARM/ARMISelLowering.cpp (-31)
  • (modified) llvm/lib/Target/ARM/ARMISelLowering.h (-2)
  • (modified) llvm/lib/Target/X86/X86ISelLowering.cpp (-111)
  • (modified) llvm/lib/Target/X86/X86ISelLowering.h (-2)
  • (modified) llvm/test/CodeGen/ARM/bswap-inline-asm.ll (+3-1)
  • (modified) llvm/test/CodeGen/X86/bswap-inline-asm.ll (+32-4)
  • (modified) llvm/test/CodeGen/X86/inline-asm-flag-clobber.ll (+3-3)
  • (modified) llvm/test/CodeGen/X86/pr67333.ll (+8-2)
diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h
index 438b6ff55c85f..291588124dccd 100644
--- a/llvm/include/llvm/CodeGen/TargetLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetLowering.h
@@ -5125,14 +5125,6 @@ class LLVM_ABI TargetLowering : public TargetLoweringBase {
   // Inline Asm Support hooks
   //
 
-  /// This hook allows the target to expand an inline asm call to be explicit
-  /// llvm code if it wants to.  This is useful for turning simple inline asms
-  /// into LLVM intrinsics, which gives the compiler more information about the
-  /// behavior of the code.
-  virtual bool ExpandInlineAsm(CallInst *) const {
-    return false;
-  }
-
   enum ConstraintType {
     C_Register,            // Constraint represents specific register(s).
     C_RegisterClass,       // Constraint represents any of register(s) in class.
diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp
index 0e40a92fd8d64..9db4c9e5e2807 100644
--- a/llvm/lib/CodeGen/CodeGenPrepare.cpp
+++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp
@@ -2618,22 +2618,9 @@ static bool despeculateCountZeros(IntrinsicInst *CountZeros, LoopInfo &LI,
 bool CodeGenPrepare::optimizeCallInst(CallInst *CI, ModifyDT &ModifiedDT) {
   BasicBlock *BB = CI->getParent();
 
-  // Lower inline assembly if we can.
-  // If we found an inline asm expession, and if the target knows how to
-  // lower it to normal LLVM code, do so now.
-  if (CI->isInlineAsm()) {
-    if (TLI->ExpandInlineAsm(CI)) {
-      // Avoid invalidating the iterator.
-      CurInstIterator = BB->begin();
-      // Avoid processing instructions out of order, which could cause
-      // reuse before a value is defined.
-      SunkAddrs.clear();
-      return true;
-    }
-    // Sink address computing for memory operands into the block.
-    if (optimizeInlineAsmInst(CI))
-      return true;
-  }
+  // Sink address computing for memory operands into the block.
+  if (CI->isInlineAsm() && optimizeInlineAsmInst(CI))
+    return true;
 
   // Align the pointer arguments to this call if the target thinks it's a good
   // idea
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index 22ba30b734a16..5ac09e2f9fb1c 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -20192,37 +20192,6 @@ bool ARMTargetLowering::SimplifyDemandedBitsForTargetNode(
 //                           ARM Inline Assembly Support
 //===----------------------------------------------------------------------===//
 
-bool ARMTargetLowering::ExpandInlineAsm(CallInst *CI) const {
-  // Looking for "rev" which is V6+.
-  if (!Subtarget->hasV6Ops())
-    return false;
-
-  InlineAsm *IA = cast<InlineAsm>(CI->getCalledOperand());
-  StringRef AsmStr = IA->getAsmString();
-  SmallVector<StringRef, 4> AsmPieces;
-  SplitString(AsmStr, AsmPieces, ";\n");
-
-  switch (AsmPieces.size()) {
-  default: return false;
-  case 1:
-    AsmStr = AsmPieces[0];
-    AsmPieces.clear();
-    SplitString(AsmStr, AsmPieces, " \t,");
-
-    // rev $0, $1
-    if (AsmPieces.size() == 3 && AsmPieces[0] == "rev" &&
-        AsmPieces[1] == "$0" && AsmPieces[2] == "$1" &&
-        IA->getConstraintString().starts_with("=l,l")) {
-      IntegerType *Ty = dyn_cast<IntegerType>(CI->getType());
-      if (Ty && Ty->getBitWidth() == 32)
-        return IntrinsicLowering::LowerToByteSwap(CI);
-    }
-    break;
-  }
-
-  return false;
-}
-
 const char *ARMTargetLowering::LowerXConstraint(EVT ConstraintVT) const {
   // At this point, we have to lower this constraint to something else, so we
   // lower it to an "r" or "w". However, by doing this we will force the result
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.h b/llvm/lib/Target/ARM/ARMISelLowering.h
index 196ecb1b9f678..955e47bf033fc 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.h
+++ b/llvm/lib/Target/ARM/ARMISelLowering.h
@@ -534,8 +534,6 @@ class VectorType;
                                       const APInt &DemandedElts,
                                       TargetLoweringOpt &TLO) const override;
 
-    bool ExpandInlineAsm(CallInst *CI) const override;
-
     ConstraintType getConstraintType(StringRef Constraint) const override;
 
     /// Examine constraint string and operand type and determine a weight value.
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 572cfdad3c93b..0110b1ed23656 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -61005,117 +61005,6 @@ bool X86TargetLowering::IsDesirableToPromoteOp(SDValue Op, EVT &PVT) const {
 //                           X86 Inline Assembly Support
 //===----------------------------------------------------------------------===//
 
-// Helper to match a string separated by whitespace.
-static bool matchAsm(StringRef S, ArrayRef<const char *> Pieces) {
-  S = S.substr(S.find_first_not_of(" \t")); // Skip leading whitespace.
-
-  for (StringRef Piece : Pieces) {
-    if (!S.starts_with(Piece)) // Check if the piece matches.
-      return false;
-
-    S = S.substr(Piece.size());
-    StringRef::size_type Pos = S.find_first_not_of(" \t");
-    if (Pos == 0) // We matched a prefix.
-      return false;
-
-    S = S.substr(Pos);
-  }
-
-  return S.empty();
-}
-
-static bool clobbersFlagRegisters(const SmallVector<StringRef, 4> &AsmPieces) {
-
-  if (AsmPieces.size() == 3 || AsmPieces.size() == 4) {
-    if (llvm::is_contained(AsmPieces, "~{cc}") &&
-        llvm::is_contained(AsmPieces, "~{flags}") &&
-        llvm::is_contained(AsmPieces, "~{fpsr}")) {
-
-      if (AsmPieces.size() == 3)
-        return true;
-      else if (llvm::is_contained(AsmPieces, "~{dirflag}"))
-        return true;
-    }
-  }
-  return false;
-}
-
-bool X86TargetLowering::ExpandInlineAsm(CallInst *CI) const {
-  InlineAsm *IA = cast<InlineAsm>(CI->getCalledOperand());
-
-  StringRef AsmStr = IA->getAsmString();
-
-  IntegerType *Ty = dyn_cast<IntegerType>(CI->getType());
-  if (!Ty || Ty->getBitWidth() % 16 != 0)
-    return false;
-
-  // TODO: should remove alternatives from the asmstring: "foo {a|b}" -> "foo a"
-  SmallVector<StringRef, 4> AsmPieces;
-  SplitString(AsmStr, AsmPieces, ";\n");
-
-  switch (AsmPieces.size()) {
-  default: return false;
-  case 1:
-    // FIXME: this should verify that we are targeting a 486 or better.  If not,
-    // we will turn this bswap into something that will be lowered to logical
-    // ops instead of emitting the bswap asm.  For now, we don't support 486 or
-    // lower so don't worry about this.
-    // bswap $0
-    if (matchAsm(AsmPieces[0], {"bswap", "$0"}) ||
-        matchAsm(AsmPieces[0], {"bswapl", "$0"}) ||
-        matchAsm(AsmPieces[0], {"bswapq", "$0"}) ||
-        matchAsm(AsmPieces[0], {"bswap", "${0:q}"}) ||
-        matchAsm(AsmPieces[0], {"bswapl", "${0:q}"}) ||
-        matchAsm(AsmPieces[0], {"bswapq", "${0:q}"})) {
-      // No need to check constraints, nothing other than the equivalent of
-      // "=r,0" would be valid here.
-      return IntrinsicLowering::LowerToByteSwap(CI);
-    }
-
-    // rorw $$8, ${0:w}  -->  llvm.bswap.i16
-    if (CI->getType()->isIntegerTy(16) &&
-        IA->getConstraintString().starts_with("=r,0,") &&
-        (matchAsm(AsmPieces[0], {"rorw", "$$8,", "${0:w}"}) ||
-         matchAsm(AsmPieces[0], {"rolw", "$$8,", "${0:w}"}))) {
-      AsmPieces.clear();
-      StringRef ConstraintsStr = IA->getConstraintString();
-      SplitString(StringRef(ConstraintsStr).substr(5), AsmPieces, ",");
-      array_pod_sort(AsmPieces.begin(), AsmPieces.end());
-      if (clobbersFlagRegisters(AsmPieces))
-        return IntrinsicLowering::LowerToByteSwap(CI);
-    }
-    break;
-  case 3:
-    if (CI->getType()->isIntegerTy(32) &&
-        IA->getConstraintString().starts_with("=r,0,") &&
-        matchAsm(AsmPieces[0], {"rorw", "$$8,", "${0:w}"}) &&
-        matchAsm(AsmPieces[1], {"rorl", "$$16,", "$0"}) &&
-        matchAsm(AsmPieces[2], {"rorw", "$$8,", "${0:w}"})) {
-      AsmPieces.clear();
-      StringRef ConstraintsStr = IA->getConstraintString();
-      SplitString(StringRef(ConstraintsStr).substr(5), AsmPieces, ",");
-      array_pod_sort(AsmPieces.begin(), AsmPieces.end());
-      if (clobbersFlagRegisters(AsmPieces))
-        return IntrinsicLowering::LowerToByteSwap(CI);
-    }
-
-    if (CI->getType()->isIntegerTy(64)) {
-      InlineAsm::ConstraintInfoVector Constraints = IA->ParseConstraints();
-      if (Constraints.size() >= 2 &&
-          Constraints[0].Codes.size() == 1 && Constraints[0].Codes[0] == "A" &&
-          Constraints[1].Codes.size() == 1 && Constraints[1].Codes[0] == "0") {
-        // bswap %eax / bswap %edx / xchgl %eax, %edx  -> llvm.bswap.i64
-        if (matchAsm(AsmPieces[0], {"bswap", "%eax"}) &&
-            matchAsm(AsmPieces[1], {"bswap", "%edx"}) &&
-            matchAsm(AsmPieces[2], {"xchgl", "%eax,", "%edx"}))
-          return IntrinsicLowering::LowerToByteSwap(CI);
-      }
-    }
-    break;
-  }
-  return false;
-}
-
 static X86::CondCode parseConstraintCode(llvm::StringRef Constraint) {
   X86::CondCode Cond = StringSwitch<X86::CondCode>(Constraint)
                            .Case("{@cca}", X86::COND_A)
diff --git a/llvm/lib/Target/X86/X86ISelLowering.h b/llvm/lib/Target/X86/X86ISelLowering.h
index d888f9f593ee7..0c9ba591b03eb 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.h
+++ b/llvm/lib/Target/X86/X86ISelLowering.h
@@ -1364,8 +1364,6 @@ namespace llvm {
 
     SDValue getReturnAddressFrameIndex(SelectionDAG &DAG) const;
 
-    bool ExpandInlineAsm(CallInst *CI) const override;
-
     ConstraintType getConstraintType(StringRef Constraint) const override;
 
     /// Examine constraint string and operand type and determine a weight value.
diff --git a/llvm/test/CodeGen/ARM/bswap-inline-asm.ll b/llvm/test/CodeGen/ARM/bswap-inline-asm.ll
index 31f9d729cf6e6..cc92a9710c98a 100644
--- a/llvm/test/CodeGen/ARM/bswap-inline-asm.ll
+++ b/llvm/test/CodeGen/ARM/bswap-inline-asm.ll
@@ -1,8 +1,10 @@
 ; RUN: llc < %s -mtriple=arm-apple-darwin -mattr=+v6 | FileCheck %s
 
+; rev inline assembly should be preserved as-is.
+
 define i32 @t1(i32 %x) nounwind {
 ; CHECK-LABEL: t1:
-; CHECK-NOT: InlineAsm
+; CHECK: InlineAsm
 ; CHECK: rev
   %asmtmp = tail call i32 asm "rev $0, $1\0A", "=l,l"(i32 %x) nounwind
   ret i32 %asmtmp
diff --git a/llvm/test/CodeGen/X86/bswap-inline-asm.ll b/llvm/test/CodeGen/X86/bswap-inline-asm.ll
index e5ffec7801fc5..a9ce616b7eccc 100644
--- a/llvm/test/CodeGen/X86/bswap-inline-asm.ll
+++ b/llvm/test/CodeGen/X86/bswap-inline-asm.ll
@@ -1,11 +1,15 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
 ; RUN: llc < %s -mtriple=x86_64-apple-darwin | FileCheck %s
 
+; bswap inline assembly should be preserved as-is.
+
 define i64 @foo(i64 %x) nounwind {
 ; CHECK-LABEL: foo:
 ; CHECK:       ## %bb.0:
 ; CHECK-NEXT:    movq %rdi, %rax
+; CHECK-NEXT:    ## InlineAsm Start
 ; CHECK-NEXT:    bswapq %rax
+; CHECK-NEXT:    ## InlineAsm End
 ; CHECK-NEXT:    retq
 	%asmtmp = tail call i64 asm "bswap $0", "=r,0,~{dirflag},~{fpsr},~{flags}"(i64 %x) nounwind
 	ret i64 %asmtmp
@@ -15,7 +19,9 @@ define i64 @bar(i64 %x) nounwind {
 ; CHECK-LABEL: bar:
 ; CHECK:       ## %bb.0:
 ; CHECK-NEXT:    movq %rdi, %rax
+; CHECK-NEXT:    ## InlineAsm Start
 ; CHECK-NEXT:    bswapq %rax
+; CHECK-NEXT:    ## InlineAsm End
 ; CHECK-NEXT:    retq
 	%asmtmp = tail call i64 asm "bswapq ${0:q}", "=r,0,~{dirflag},~{fpsr},~{flags}"(i64 %x) nounwind
 	ret i64 %asmtmp
@@ -25,16 +31,20 @@ define i32 @pen(i32 %x) nounwind {
 ; CHECK-LABEL: pen:
 ; CHECK:       ## %bb.0:
 ; CHECK-NEXT:    movl %edi, %eax
+; CHECK-NEXT:    ## InlineAsm Start
 ; CHECK-NEXT:    bswapl %eax
+; CHECK-NEXT:    ## InlineAsm End
 ; CHECK-NEXT:    retq
-	%asmtmp = tail call i32 asm "bswapl ${0:q}", "=r,0,~{dirflag},~{fpsr},~{flags}"(i32 %x) nounwind
+	%asmtmp = tail call i32 asm "bswapl ${0:k}", "=r,0,~{dirflag},~{fpsr},~{flags}"(i32 %x) nounwind
 	ret i32 %asmtmp
 }
 
 define zeroext i16 @s16(i16 zeroext %x) nounwind {
 ; CHECK-LABEL: s16:
 ; CHECK:       ## %bb.0:
-; CHECK-NEXT:    rolw $8, %di
+; CHECK-NEXT:    ## InlineAsm Start
+; CHECK-NEXT:    rorw $8, %di
+; CHECK-NEXT:    ## InlineAsm End
 ; CHECK-NEXT:    movzwl %di, %eax
 ; CHECK-NEXT:    retq
   %asmtmp = tail call i16 asm "rorw $$8, ${0:w}", "=r,0,~{dirflag},~{fpsr},~{flags},~{cc}"(i16 %x) nounwind
@@ -44,7 +54,9 @@ define zeroext i16 @s16(i16 zeroext %x) nounwind {
 define zeroext i16 @t16(i16 zeroext %x) nounwind {
 ; CHECK-LABEL: t16:
 ; CHECK:       ## %bb.0:
-; CHECK-NEXT:    rolw $8, %di
+; CHECK-NEXT:    ## InlineAsm Start
+; CHECK-NEXT:    rorw $8, %di
+; CHECK-NEXT:    ## InlineAsm End
 ; CHECK-NEXT:    movzwl %di, %eax
 ; CHECK-NEXT:    retq
   %asmtmp = tail call i16 asm "rorw $$8, ${0:w}", "=r,0,~{cc},~{dirflag},~{fpsr},~{flags}"(i16 %x) nounwind
@@ -54,7 +66,9 @@ define zeroext i16 @t16(i16 zeroext %x) nounwind {
 define zeroext i16 @u16(i16 zeroext %x) nounwind {
 ; CHECK-LABEL: u16:
 ; CHECK:       ## %bb.0:
+; CHECK-NEXT:    ## InlineAsm Start
 ; CHECK-NEXT:    rolw $8, %di
+; CHECK-NEXT:    ## InlineAsm End
 ; CHECK-NEXT:    movzwl %di, %eax
 ; CHECK-NEXT:    retq
   %asmtmp = tail call i16 asm "rolw $$8, ${0:w}", "=r,0,~{dirflag},~{fpsr},~{flags},~{cc}"(i16 %x) nounwind
@@ -64,7 +78,9 @@ define zeroext i16 @u16(i16 zeroext %x) nounwind {
 define zeroext i16 @v16(i16 zeroext %x) nounwind {
 ; CHECK-LABEL: v16:
 ; CHECK:       ## %bb.0:
+; CHECK-NEXT:    ## InlineAsm Start
 ; CHECK-NEXT:    rolw $8, %di
+; CHECK-NEXT:    ## InlineAsm End
 ; CHECK-NEXT:    movzwl %di, %eax
 ; CHECK-NEXT:    retq
   %asmtmp = tail call i16 asm "rolw $$8, ${0:w}", "=r,0,~{cc},~{dirflag},~{fpsr},~{flags}"(i16 %x) nounwind
@@ -75,7 +91,9 @@ define i32 @s32(i32 %x) nounwind {
 ; CHECK-LABEL: s32:
 ; CHECK:       ## %bb.0:
 ; CHECK-NEXT:    movl %edi, %eax
+; CHECK-NEXT:    ## InlineAsm Start
 ; CHECK-NEXT:    bswapl %eax
+; CHECK-NEXT:    ## InlineAsm End
 ; CHECK-NEXT:    retq
   %asmtmp = tail call i32 asm "bswap $0", "=r,0,~{dirflag},~{fpsr},~{flags}"(i32 %x) nounwind
   ret i32 %asmtmp
@@ -85,7 +103,9 @@ define i32 @t32(i32 %x) nounwind {
 ; CHECK-LABEL: t32:
 ; CHECK:       ## %bb.0:
 ; CHECK-NEXT:    movl %edi, %eax
+; CHECK-NEXT:    ## InlineAsm Start
 ; CHECK-NEXT:    bswapl %eax
+; CHECK-NEXT:    ## InlineAsm End
 ; CHECK-NEXT:    retq
   %asmtmp = tail call i32 asm "bswap $0", "=r,0,~{dirflag},~{flags},~{fpsr}"(i32 %x) nounwind
   ret i32 %asmtmp
@@ -95,7 +115,11 @@ define i32 @u32(i32 %x) nounwind {
 ; CHECK-LABEL: u32:
 ; CHECK:       ## %bb.0:
 ; CHECK-NEXT:    movl %edi, %eax
-; CHECK-NEXT:    bswapl %eax
+; CHECK-NEXT:    ## InlineAsm Start
+; CHECK-NEXT:    rorw $8, %ax
+; CHECK-NEXT:    rorl $16, %eax
+; CHECK-NEXT:    rorw $8, %ax
+; CHECK-NEXT:    ## InlineAsm End
 ; CHECK-NEXT:    retq
   %asmtmp = tail call i32 asm "rorw $$8, ${0:w};rorl $$16, $0;rorw $$8, ${0:w}", "=r,0,~{cc},~{dirflag},~{flags},~{fpsr}"(i32 %x) nounwind
   ret i32 %asmtmp
@@ -105,7 +129,9 @@ define i64 @s64(i64 %x) nounwind {
 ; CHECK-LABEL: s64:
 ; CHECK:       ## %bb.0:
 ; CHECK-NEXT:    movq %rdi, %rax
+; CHECK-NEXT:    ## InlineAsm Start
 ; CHECK-NEXT:    bswapq %rax
+; CHECK-NEXT:    ## InlineAsm End
 ; CHECK-NEXT:    retq
   %asmtmp = tail call i64 asm "bswap ${0:q}", "=r,0,~{dirflag},~{fpsr},~{flags}"(i64 %x) nounwind
   ret i64 %asmtmp
@@ -115,7 +141,9 @@ define i64 @t64(i64 %x) nounwind {
 ; CHECK-LABEL: t64:
 ; CHECK:       ## %bb.0:
 ; CHECK-NEXT:    movq %rdi, %rax
+; CHECK-NEXT:    ## InlineAsm Start
 ; CHECK-NEXT:    bswapq %rax
+; CHECK-NEXT:    ## InlineAsm End
 ; CHECK-NEXT:    retq
   %asmtmp = tail call i64 asm "bswap ${0:q}", "=r,0,~{fpsr},~{dirflag},~{flags}"(i64 %x) nounwind
   ret i64 %asmtmp
diff --git a/llvm/test/CodeGen/X86/inline-asm-flag-clobber.ll b/llvm/test/CodeGen/X86/inline-asm-flag-clobber.ll
index 57dccfc1b4a84..0538541a6f7ba 100644
--- a/llvm/test/CodeGen/X86/inline-asm-flag-clobber.ll
+++ b/llvm/test/CodeGen/X86/inline-asm-flag-clobber.ll
@@ -18,9 +18,9 @@ define i64 @t(ptr %arg) nounwind {
         ret i64 0
 }
 
-; Make sure that we translate this to the bswap intrinsic which lowers down without the
-; inline assembly.
-; CHECK-NOT: #APP
+; Make sure this lowers to inline assembly and is not translated to an
+; intrinsic.
+; CHECK: #APP
 define i32 @s(i32 %argc, ptr nocapture %argv) unnamed_addr nounwind {
 entry:
   %0 = trunc i32 %argc to i16
diff --git a/llvm/test/CodeGen/X86/pr67333.ll b/llvm/test/CodeGen/X86/pr67333.ll
index cbb730857506d..accdd04f084df 100644
--- a/llvm/test/CodeGen/X86/pr67333.ll
+++ b/llvm/test/CodeGen/X86/pr67333.ll
@@ -7,8 +7,14 @@ declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #0
 define void @SHA256_Compress_Generic(ptr noundef %ctx) #1 {
 ; CHECK-LABEL: SHA256_Compress_Generic:
 ; CHECK:       # %bb.0: # %entry
-; CHECK-NEXT:    movbel 0, %eax
-; CHECK-NEXT:    movbel 12(%rdi), %ecx
+; CHECK-NEXT:    movl 0, %eax
+; CHECK-NEXT:    #APP
+; CHECK-NEXT:    bswapl %eax
+; CHECK-NEXT:    #NO_APP
+; CHECK-NEXT:    movl 12(%rdi), %ecx
+; CHECK-NEXT:    #APP
+; CHECK-NEXT:    bswapl %ecx
+; CHECK-NEXT:    #NO_APP
 ; CHECK-NEXT:    vmovd %eax, %xmm0
 ; CHECK-NEXT:    vmovdqa {{.*#+}} xmm1 = [128,128,128,128,0,1,2,3,128,128,128,128,128,128,128,128]
 ; CHECK-NEXT:    vpshufb %xmm1, %xmm0, %xmm2

Copy link
Member

@jyknight jyknight left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

Copy link
Collaborator

@rnk rnk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's do it. :)

@nikic nikic merged commit 3f757a3 into llvm:main Sep 4, 2025
12 checks passed
@nikic nikic deleted the expand-inline-asm branch September 4, 2025 07:28
@llvm-ci
Copy link
Collaborator

llvm-ci commented Sep 4, 2025

LLVM Buildbot has detected a new failure on builder lldb-aarch64-ubuntu running on linaro-lldb-aarch64-ubuntu while building llvm at step 6 "test".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/59/builds/23660

Here is the relevant piece of the build log for the reference
Step 6 (test) failure: build (failure)
...
PASS: lldb-unit :: ValueObject/./LLDBValueObjectTests/8/12 (2305 of 2314)
PASS: lldb-unit :: ValueObject/./LLDBValueObjectTests/9/12 (2306 of 2314)
PASS: lldb-unit :: tools/lldb-server/tests/./LLDBServerTests/0/2 (2307 of 2314)
PASS: lldb-unit :: tools/lldb-server/tests/./LLDBServerTests/1/2 (2308 of 2314)
PASS: lldb-unit :: Utility/./UtilityTests/7/8 (2309 of 2314)
PASS: lldb-unit :: Host/./HostTests/5/9 (2310 of 2314)
PASS: lldb-unit :: Target/./TargetTests/11/14 (2311 of 2314)
PASS: lldb-unit :: Host/./HostTests/8/9 (2312 of 2314)
PASS: lldb-unit :: Process/gdb-remote/./ProcessGdbRemoteTests/8/9 (2313 of 2314)
UNRESOLVED: lldb-api :: tools/lldb-server/TestLldbGdbServer.py (2314 of 2314)
******************** TEST 'lldb-api :: tools/lldb-server/TestLldbGdbServer.py' FAILED ********************
Script:
--
/usr/bin/python3.10 /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/test/API/dotest.py -u CXXFLAGS -u CFLAGS --env LLVM_LIBS_DIR=/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./lib --env LLVM_INCLUDE_DIR=/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/include --env LLVM_TOOLS_DIR=/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./bin --arch aarch64 --build-dir /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/lldb-test-build.noindex --lldb-module-cache-dir /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/lldb-test-build.noindex/module-cache-lldb/lldb-api --clang-module-cache-dir /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/lldb-test-build.noindex/module-cache-clang/lldb-api --executable /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./bin/lldb --compiler /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./bin/clang --dsymutil /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./bin/dsymutil --make /usr/bin/gmake --llvm-tools-dir /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./bin --lldb-obj-root /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/tools/lldb --lldb-libs-dir /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./lib --cmake-build-type Release /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/test/API/tools/lldb-server -p TestLldbGdbServer.py
--
Exit Code: 1

Command Output (stdout):
--
lldb version 22.0.0git (https://github.com/llvm/llvm-project.git revision 3f757a39f2855cd06c62a85b8e27fd56fa017e78)
  clang revision 3f757a39f2855cd06c62a85b8e27fd56fa017e78
  llvm revision 3f757a39f2855cd06c62a85b8e27fd56fa017e78
Skipping the following test categories: ['libc++', 'msvcstl', 'dsym', 'gmodules', 'debugserver', 'objc']

--
Command Output (stderr):
--
UNSUPPORTED: LLDB (/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang-aarch64) :: test_Hc_then_Csignal_signals_correct_thread_launch_debugserver (TestLldbGdbServer.LldbGdbServerTestCase) (test case does not fall in any category of interest for this run) 
PASS: LLDB (/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang-aarch64) :: test_Hc_then_Csignal_signals_correct_thread_launch_llgs (TestLldbGdbServer.LldbGdbServerTestCase)
PASS: LLDB (/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang-aarch64) :: test_Hg_fails_on_another_pid_llgs (TestLldbGdbServer.LldbGdbServerTestCase)
PASS: LLDB (/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang-aarch64) :: test_Hg_fails_on_minus_one_pid_llgs (TestLldbGdbServer.LldbGdbServerTestCase)
PASS: LLDB (/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang-aarch64) :: test_Hg_fails_on_zero_pid_llgs (TestLldbGdbServer.LldbGdbServerTestCase)
UNSUPPORTED: LLDB (/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang-aarch64) :: test_Hg_switches_to_3_threads_launch_debugserver (TestLldbGdbServer.LldbGdbServerTestCase) (test case does not fall in any category of interest for this run) 
PASS: LLDB (/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang-aarch64) :: test_Hg_switches_to_3_threads_launch_llgs (TestLldbGdbServer.LldbGdbServerTestCase)
UNSUPPORTED: LLDB (/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang-aarch64) :: test_P_and_p_thread_suffix_work_debugserver (TestLldbGdbServer.LldbGdbServerTestCase) (test case does not fall in any category of interest for this run) 
PASS: LLDB (/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang-aarch64) :: test_P_and_p_thread_suffix_work_llgs (TestLldbGdbServer.LldbGdbServerTestCase)
UNSUPPORTED: LLDB (/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang-aarch64) :: test_P_writes_all_gpr_registers_debugserver (TestLldbGdbServer.LldbGdbServerTestCase) (test case does not fall in any category of interest for this run) 
PASS: LLDB (/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang-aarch64) :: test_P_writes_all_gpr_registers_llgs (TestLldbGdbServer.LldbGdbServerTestCase)
UNSUPPORTED: LLDB (/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang-aarch64) :: test_attach_commandline_continue_app_exits_debugserver (TestLldbGdbServer.LldbGdbServerTestCase) (test case does not fall in any category of interest for this run) 
lldb-server exiting...
PASS: LLDB (/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang-aarch64) :: test_attach_commandline_continue_app_exits_llgs (TestLldbGdbServer.LldbGdbServerTestCase)
UNSUPPORTED: LLDB (/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang-aarch64) :: test_c_packet_works_debugserver (TestLldbGdbServer.LldbGdbServerTestCase) (test case does not fall in any category of interest for this run) 
lldb-server exiting...
PASS: LLDB (/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang-aarch64) :: test_c_packet_works_llgs (TestLldbGdbServer.LldbGdbServerTestCase)
UNSUPPORTED: LLDB (/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang-aarch64) :: test_first_launch_stop_reply_thread_matches_first_qC_debugserver (TestLldbGdbServer.LldbGdbServerTestCase) (test case does not fall in any category of interest for this run) 
PASS: LLDB (/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang-aarch64) :: test_first_launch_stop_reply_thread_matches_first_qC_llgs (TestLldbGdbServer.LldbGdbServerTestCase)
UNSUPPORTED: LLDB (/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang-aarch64) :: test_hardware_breakpoint_set_and_remove_work_debugserver (TestLldbGdbServer.LldbGdbServerTestCase) (test case does not fall in any category of interest for this run) 
lldb-server exiting...
PASS: LLDB (/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang-aarch64) :: test_hardware_breakpoint_set_and_remove_work_llgs (TestLldbGdbServer.LldbGdbServerTestCase)

@llvm-ci
Copy link
Collaborator

llvm-ci commented Sep 4, 2025

LLVM Buildbot has detected a new failure on builder llvm-clang-x86_64-darwin running on doug-worker-3 while building llvm at step 6 "test-build-unified-tree-check-all".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/23/builds/13570

Here is the relevant piece of the build log for the reference
Step 6 (test-build-unified-tree-check-all) failure: test (failure)
******************** TEST 'lld :: MinGW/driver.test' FAILED ********************
Exit Code: 127

Command Output (stdout):
--
# RUN: at line 1
/Volumes/RAMDisk/buildbot-root/x86_64-darwin/build/bin/ld.lld -### foo.o -m i386pe 2>&1 | /Volumes/RAMDisk/buildbot-root/x86_64-darwin/build/bin/FileCheck -check-prefix=X86 /Volumes/RAMDisk/buildbot-root/x86_64-darwin/llvm-project/lld/test/MinGW/driver.test
# executed command: /Volumes/RAMDisk/buildbot-root/x86_64-darwin/build/bin/ld.lld '-###' foo.o -m i386pe
# note: command had no output on stdout or stderr
# executed command: /Volumes/RAMDisk/buildbot-root/x86_64-darwin/build/bin/FileCheck -check-prefix=X86 /Volumes/RAMDisk/buildbot-root/x86_64-darwin/llvm-project/lld/test/MinGW/driver.test
# note: command had no output on stdout or stderr
# RUN: at line 7
echo "-### foo.o -m i386pe" > /Volumes/RAMDisk/buildbot-root/x86_64-darwin/build/tools/lld/test/MinGW/Output/driver.test.tmp.rsp
# executed command: echo '-### foo.o -m i386pe'
# note: command had no output on stdout or stderr
# RUN: at line 8
/Volumes/RAMDisk/buildbot-root/x86_64-darwin/build/bin/ld.lld @/Volumes/RAMDisk/buildbot-root/x86_64-darwin/build/tools/lld/test/MinGW/Output/driver.test.tmp.rsp 2>&1 | /Volumes/RAMDisk/buildbot-root/x86_64-darwin/build/bin/FileCheck -check-prefix=X86 /Volumes/RAMDisk/buildbot-root/x86_64-darwin/llvm-project/lld/test/MinGW/driver.test
# executed command: /Volumes/RAMDisk/buildbot-root/x86_64-darwin/build/bin/ld.lld @/Volumes/RAMDisk/buildbot-root/x86_64-darwin/build/tools/lld/test/MinGW/Output/driver.test.tmp.rsp
# note: command had no output on stdout or stderr
# executed command: /Volumes/RAMDisk/buildbot-root/x86_64-darwin/build/bin/FileCheck -check-prefix=X86 /Volumes/RAMDisk/buildbot-root/x86_64-darwin/llvm-project/lld/test/MinGW/driver.test
# note: command had no output on stdout or stderr
# RUN: at line 10
/Volumes/RAMDisk/buildbot-root/x86_64-darwin/build/bin/ld.lld -### foo.o -m i386pep 2>&1 | /Volumes/RAMDisk/buildbot-root/x86_64-darwin/build/bin/FileCheck -check-prefix=X64 /Volumes/RAMDisk/buildbot-root/x86_64-darwin/llvm-project/lld/test/MinGW/driver.test
# executed command: /Volumes/RAMDisk/buildbot-root/x86_64-darwin/build/bin/ld.lld '-###' foo.o -m i386pep
# note: command had no output on stdout or stderr
# executed command: /Volumes/RAMDisk/buildbot-root/x86_64-darwin/build/bin/FileCheck -check-prefix=X64 /Volumes/RAMDisk/buildbot-root/x86_64-darwin/llvm-project/lld/test/MinGW/driver.test
# note: command had no output on stdout or stderr
# RUN: at line 16
/Volumes/RAMDisk/buildbot-root/x86_64-darwin/build/bin/ld.lld -### foo.o -m thumb2pe 2>&1 | /Volumes/RAMDisk/buildbot-root/x86_64-darwin/build/bin/FileCheck -check-prefix=ARM /Volumes/RAMDisk/buildbot-root/x86_64-darwin/llvm-project/lld/test/MinGW/driver.test
# executed command: /Volumes/RAMDisk/buildbot-root/x86_64-darwin/build/bin/ld.lld '-###' foo.o -m thumb2pe
# note: command had no output on stdout or stderr
# executed command: /Volumes/RAMDisk/buildbot-root/x86_64-darwin/build/bin/FileCheck -check-prefix=ARM /Volumes/RAMDisk/buildbot-root/x86_64-darwin/llvm-project/lld/test/MinGW/driver.test
# note: command had no output on stdout or stderr
# RUN: at line 22
/Volumes/RAMDisk/buildbot-root/x86_64-darwin/build/bin/ld.lld -### foo.o -m arm64pe 2>&1 | /Volumes/RAMDisk/buildbot-root/x86_64-darwin/build/bin/FileCheck -check-prefix=ARM64 /Volumes/RAMDisk/buildbot-root/x86_64-darwin/llvm-project/lld/test/MinGW/driver.test
# executed command: /Volumes/RAMDisk/buildbot-root/x86_64-darwin/build/bin/ld.lld '-###' foo.o -m arm64pe
# note: command had no output on stdout or stderr
# executed command: /Volumes/RAMDisk/buildbot-root/x86_64-darwin/build/bin/FileCheck -check-prefix=ARM64 /Volumes/RAMDisk/buildbot-root/x86_64-darwin/llvm-project/lld/test/MinGW/driver.test
# note: command had no output on stdout or stderr
# RUN: at line 28
/Volumes/RAMDisk/buildbot-root/x86_64-darwin/build/bin/ld.lld -### foo.o -m arm64ecpe 2>&1 | /Volumes/RAMDisk/buildbot-root/x86_64-darwin/build/bin/FileCheck -check-prefix=ARM64EC /Volumes/RAMDisk/buildbot-root/x86_64-darwin/llvm-project/lld/test/MinGW/driver.test
# executed command: /Volumes/RAMDisk/buildbot-root/x86_64-darwin/build/bin/ld.lld '-###' foo.o -m arm64ecpe
# note: command had no output on stdout or stderr
# executed command: /Volumes/RAMDisk/buildbot-root/x86_64-darwin/build/bin/FileCheck -check-prefix=ARM64EC /Volumes/RAMDisk/buildbot-root/x86_64-darwin/llvm-project/lld/test/MinGW/driver.test
# note: command had no output on stdout or stderr
# RUN: at line 34
/Volumes/RAMDisk/buildbot-root/x86_64-darwin/build/bin/ld.lld -### foo.o -m arm64xpe 2>&1 | /Volumes/RAMDisk/buildbot-root/x86_64-darwin/build/bin/FileCheck -check-prefix=ARM64X /Volumes/RAMDisk/buildbot-root/x86_64-darwin/llvm-project/lld/test/MinGW/driver.test
# executed command: /Volumes/RAMDisk/buildbot-root/x86_64-darwin/build/bin/ld.lld '-###' foo.o -m arm64xpe
# note: command had no output on stdout or stderr
# executed command: /Volumes/RAMDisk/buildbot-root/x86_64-darwin/build/bin/FileCheck -check-prefix=ARM64X /Volumes/RAMDisk/buildbot-root/x86_64-darwin/llvm-project/lld/test/MinGW/driver.test
...

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.

Delete ExpandInlineAsm
7 participants