Skip to content

Conversation

@anoopkg6
Copy link
Contributor

Fix #173673: Add flag output operand info to ConstraintInfo enum to distinguish getOutputOperandBounds for flag output operand bounds.

anoopkg6 added 2 commits January 12, 2026 00:12
@llvmbot llvmbot added clang Clang issues not falling into any other category backend:AArch64 backend:SystemZ clang:frontend Language frontend issues, e.g. anything involving "Sema" clang:codegen IR generation bugs: mangling, exceptions, etc. labels Jan 11, 2026
@llvmbot
Copy link
Member

llvmbot commented Jan 11, 2026

@llvm/pr-subscribers-clang
@llvm/pr-subscribers-backend-aarch64

@llvm/pr-subscribers-backend-systemz

Author: None (anoopkg6)

Changes

Fix #173673: Add flag output operand info to ConstraintInfo enum to distinguish getOutputOperandBounds for flag output operand bounds.


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

5 Files Affected:

  • (modified) clang/include/clang/Basic/TargetInfo.h (+5)
  • (modified) clang/lib/Basic/Targets/AArch64.cpp (+1)
  • (modified) clang/lib/Basic/Targets/SystemZ.cpp (+1)
  • (modified) clang/lib/Basic/Targets/X86.cpp (+1)
  • (modified) clang/lib/CodeGen/CGStmt.cpp (+4-1)
diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h
index 4ff77bb64cf1c..92cf17734511b 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -1131,6 +1131,7 @@ class TargetInfo : public TransferrableTargetInfo,
       CI_HasMatchingInput = 0x08,  // This output operand has a matching input.
       CI_ImmediateConstant = 0x10, // This operand must be an immediate constant
       CI_EarlyClobber = 0x20,      // "&" output constraint (early clobber).
+      CI_CCOutputOperand = 0x40,   // "=@cc" sets CC, Flag output operand.
     };
     unsigned Flags;
     int TiedOperand;
@@ -1168,6 +1169,9 @@ class TargetInfo : public TransferrableTargetInfo,
     /// If this returns true then getTiedOperand will indicate which output
     /// operand this is tied to.
     bool hasTiedOperand() const { return TiedOperand != -1; }
+    bool hasFlagOutputOperand() const {
+      return (Flags & CI_CCOutputOperand) != 0;
+    }
     unsigned getTiedOperand() const {
       assert(hasTiedOperand() && "Has no tied operand!");
       return (unsigned)TiedOperand;
@@ -1188,6 +1192,7 @@ class TargetInfo : public TransferrableTargetInfo,
     void setAllowsMemory() { Flags |= CI_AllowsMemory; }
     void setAllowsRegister() { Flags |= CI_AllowsRegister; }
     void setHasMatchingInput() { Flags |= CI_HasMatchingInput; }
+    void setFlagOutputOperand() { Flags |= CI_CCOutputOperand; }
     void setRequiresImmediate(int Min, int Max) {
       Flags |= CI_ImmediateConstant;
       ImmRange.Min = Min;
diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp
index ecd441be364c2..118563cea6048 100644
--- a/clang/lib/Basic/Targets/AArch64.cpp
+++ b/clang/lib/Basic/Targets/AArch64.cpp
@@ -1570,6 +1570,7 @@ bool AArch64TargetInfo::validateAsmConstraint(
     if (const unsigned Len = matchAsmCCConstraint(Name)) {
       Name += Len - 1;
       Info.setAllowsRegister();
+      Info.setFlagOutputOperand();
       Info.setOutputOperandBounds(0, 2);
       return true;
     }
diff --git a/clang/lib/Basic/Targets/SystemZ.cpp b/clang/lib/Basic/Targets/SystemZ.cpp
index ecd12ed34a20c..4723f36ba2ddb 100644
--- a/clang/lib/Basic/Targets/SystemZ.cpp
+++ b/clang/lib/Basic/Targets/SystemZ.cpp
@@ -104,6 +104,7 @@ bool SystemZTargetInfo::validateAsmConstraint(
     if (StringRef(Name) == "@cc") {
       Name += 2;
       Info.setAllowsRegister();
+      Info.setFlagOutputOperand();
       // SystemZ has 2-bits CC, and hence Interval [0, 4).
       Info.setOutputOperandBounds(0, 4);
       return true;
diff --git a/clang/lib/Basic/Targets/X86.cpp b/clang/lib/Basic/Targets/X86.cpp
index f00d435937b92..4d50cb0f813ae 100644
--- a/clang/lib/Basic/Targets/X86.cpp
+++ b/clang/lib/Basic/Targets/X86.cpp
@@ -1512,6 +1512,7 @@ bool X86TargetInfo::validateAsmConstraint(
     if (auto Len = matchAsmCCConstraint(Name)) {
       Name += Len - 1;
       Info.setAllowsRegister();
+      Info.setFlagOutputOperand();
       Info.setOutputOperandBounds(0, 2);
       return true;
     }
diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
index c050fd41ac0e9..a19e2e68b3ec2 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/lib/CodeGen/CGStmt.cpp
@@ -2968,7 +2968,10 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {
       ResultRegQualTys.push_back(QTy);
       ResultRegDests.push_back(Dest);
 
-      ResultBounds.emplace_back(Info.getOutputOperandBounds());
+      ResultBounds.emplace_back(
+          Info.hasFlagOutputOperand()
+              ? Info.getOutputOperandBounds()
+              : std::optional<std::pair<unsigned, unsigned>>());
 
       llvm::Type *Ty = ConvertTypeForMem(QTy);
       const bool RequiresCast = Info.allowsRegister() &&

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

Labels

backend:AArch64 backend:SystemZ clang:codegen IR generation bugs: mangling, exceptions, etc. clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

clang trunk: assertion "Output operand lower bound is not zero" in EmitAsmStores during codegen of inline asm with multiple +r and +Kr outputs

2 participants