[clang] Fix #173673 assertion "Output operand lower bound is not zero" with asm output operand with '+Kr' constarint (PR #175470)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Jan 11 15:20:52 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-systemz
Author: None (anoopkg6)
<details>
<summary>Changes</summary>
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
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() &&
``````````
</details>
https://github.com/llvm/llvm-project/pull/175470
More information about the cfe-commits
mailing list