[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
Tue Aug 2 11:49:35 PDT 2022


This revision was automatically updated to reflect the committed changes.
ychen marked an inline comment as done.
Closed by commit rG92c1bc61586c: [CodeGen][inlineasm] assume the flag output of inline asm is boolean value (authored by ychen).

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: %0 = 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.449369.patch
Type: text/x-patch
Size: 2920 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20220802/94808426/attachment.bin>


More information about the cfe-commits mailing list