[PATCH] D129954: [CodeGen][inlineasm] assume the flag output of inline asm is boolean value
Yuanfang Chen via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Fri Jul 29 15:29:15 PDT 2022
ychen updated this revision to Diff 448732.
ychen added a comment.
- use < 2
- check multiple flag outputs
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D129954/new/
https://reviews.llvm.org/D129954
Files:
clang/lib/CodeGen/CGStmt.cpp
clang/test/CodeGen/inline-asm-x86-flag-output.c
Index: clang/test/CodeGen/inline-asm-x86-flag-output.c
===================================================================
--- clang/test/CodeGen/inline-asm-x86-flag-output.c
+++ clang/test/CodeGen/inline-asm-x86-flag-output.c
@@ -374,3 +374,22 @@
: "cx");
return b;
}
+
+int test_assume_boolean_flag(long nr, volatile long *addr) {
+ //CHECK-LABEL: @test_assume_boolean_flag
+ //CHECK: = tail call { i32, i32 } asm "cmp $2,$1", "={@cca},={@ccae},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* elementtype(i64) %addr, i64 %nr)
+ //CHECK: [[RES1:%.*]] = extractvalue { i32, i32 } %0, 0
+ //CHECK: [[RES2:%.*]] = extractvalue { i32, i32 } %0, 1
+ //CHECK: %1 = icmp ult i32 [[RES1]], 2
+ //CHECK: tail call void @llvm.assume(i1 %1)
+ //CHECK: %2 = icmp ult i32 [[RES2]], 2
+ //CHECK: tail call void @llvm.assume(i1 %2)
+ int x,y;
+ asm("cmp %2,%1"
+ : "=@cca"(x), "=@ccae"(y), "=m"(*(volatile long *)(addr))
+ : "r"(nr)
+ : "cc");
+ if (x)
+ return 0;
+ return 1;
+}
Index: clang/lib/CodeGen/CGStmt.cpp
===================================================================
--- clang/lib/CodeGen/CGStmt.cpp
+++ clang/lib/CodeGen/CGStmt.cpp
@@ -2343,6 +2343,7 @@
std::vector<llvm::Type *> ArgElemTypes;
std::vector<llvm::Value*> Args;
llvm::BitVector ResultTypeRequiresCast;
+ llvm::BitVector ResultRegIsFlagReg;
// Keep track of inout constraints.
std::string InOutConstraints;
@@ -2400,6 +2401,9 @@
ResultRegQualTys.push_back(QTy);
ResultRegDests.push_back(Dest);
+ bool IsFlagReg = llvm::StringRef(OutputConstraint).startswith("{@cc");
+ ResultRegIsFlagReg.push_back(IsFlagReg);
+
llvm::Type *Ty = ConvertTypeForMem(QTy);
const bool RequiresCast = Info.allowsRegister() &&
(getTargetHooks().isScalarizableAsmOperand(*this, Ty) ||
@@ -2717,10 +2721,21 @@
// ResultRegDests can be also populated by addReturnRegisterOutputs() above,
// in which case its size may grow.
assert(ResultTypeRequiresCast.size() <= ResultRegDests.size());
+ assert(ResultRegIsFlagReg.size() <= ResultRegDests.size());
for (unsigned i = 0, e = RegResults.size(); i != e; ++i) {
llvm::Value *Tmp = RegResults[i];
llvm::Type *TruncTy = ResultTruncRegTypes[i];
+ if ((i < ResultRegIsFlagReg.size()) && ResultRegIsFlagReg[i]) {
+ // Target must guarantee the Value `Tmp` here is lowered to a boolean
+ // value.
+ llvm::Constant *Two = llvm::ConstantInt::get(Tmp->getType(), 2);
+ llvm::Value *IsBooleanValue =
+ Builder.CreateCmp(llvm::CmpInst::ICMP_ULT, Tmp, Two);
+ llvm::Function *FnAssume = CGM.getIntrinsic(llvm::Intrinsic::assume);
+ Builder.CreateCall(FnAssume, IsBooleanValue);
+ }
+
// If the result type of the LLVM IR asm doesn't match the result type of
// the expression, do the conversion.
if (ResultRegTypes[i] != ResultTruncRegTypes[i]) {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D129954.448732.patch
Type: text/x-patch
Size: 2917 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20220729/6344dc2c/attachment.bin>
More information about the cfe-commits
mailing list