[Mlir-commits] [mlir] e927a33 - [mlir][LLVMIR] Add support for translating FCmp & FP constants

Min-Yih Hsu llvmlistbot at llvm.org
Mon May 2 16:23:50 PDT 2022


Author: Min-Yih Hsu
Date: 2022-05-02T16:22:35-07:00
New Revision: e927a336a58b93ea2b2cddfc511e531695273d8d

URL: https://github.com/llvm/llvm-project/commit/e927a336a58b93ea2b2cddfc511e531695273d8d
DIFF: https://github.com/llvm/llvm-project/commit/e927a336a58b93ea2b2cddfc511e531695273d8d.diff

LOG: [mlir][LLVMIR] Add support for translating FCmp & FP constants

This patch add supports for translating FCmp and more kinds of FP
constants in addition to 32 & 64-bit ones. However, we can't express
ppc_fp128 constants right now because the semantics for its underlying
APFloat is `S_PPCDoubleDouble` but mlir::FloatType doesn't support such
semantics right now.

Differential Revision: https://reviews.llvm.org/D124630

Added: 
    

Modified: 
    mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp
    mlir/test/Target/LLVMIR/Import/basic.ll

Removed: 
    


################################################################################
diff  --git a/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp b/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp
index 90c3d63b65f0a..1a734561fbef7 100644
--- a/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp
+++ b/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp
@@ -347,10 +347,14 @@ Attribute Importer::getConstantAsAttr(llvm::Constant *value) {
     if (c->isString())
       return b.getStringAttr(c->getAsString());
   if (auto *c = dyn_cast<llvm::ConstantFP>(value)) {
-    if (c->getType()->isDoubleTy())
-      return b.getFloatAttr(FloatType::getF64(context), c->getValueAPF());
-    if (c->getType()->isFloatingPointTy())
-      return b.getFloatAttr(FloatType::getF32(context), c->getValueAPF());
+    auto *type = c->getType();
+    FloatType floatTy;
+    if (type->isBFloatTy())
+      floatTy = FloatType::getBF16(context);
+    else
+      floatTy = getDLFloatType(*context, type->getScalarSizeInBits());
+    assert(floatTy && "unsupported floating point type");
+    return b.getFloatAttr(floatTy, c->getValueAPF());
   }
   if (auto *f = dyn_cast<llvm::Function>(value))
     return SymbolRefAttr::get(b.getContext(), f->getName());
@@ -607,7 +611,7 @@ static StringRef lookupOperationNameFromOpcode(unsigned opcode) {
       // FIXME: cleanuppad
       // FIXME: catchpad
       // ICmp is handled specially.
-      // FIXME: fcmp
+      // FCmp is handled specially.
       // PHI is handled specially.
       INST(Freeze, Freeze), INST(Call, Call),
       // FIXME: select
@@ -649,7 +653,47 @@ static ICmpPredicate getICmpPredicate(llvm::CmpInst::Predicate p) {
   case llvm::CmpInst::Predicate::ICMP_UGE:
     return LLVM::ICmpPredicate::uge;
   }
-  llvm_unreachable("incorrect comparison predicate");
+  llvm_unreachable("incorrect integer comparison predicate");
+}
+
+static FCmpPredicate getFCmpPredicate(llvm::CmpInst::Predicate p) {
+  switch (p) {
+  default:
+    llvm_unreachable("incorrect comparison predicate");
+  case llvm::CmpInst::Predicate::FCMP_FALSE:
+    return LLVM::FCmpPredicate::_false;
+  case llvm::CmpInst::Predicate::FCMP_TRUE:
+    return LLVM::FCmpPredicate::_true;
+  case llvm::CmpInst::Predicate::FCMP_OEQ:
+    return LLVM::FCmpPredicate::oeq;
+  case llvm::CmpInst::Predicate::FCMP_ONE:
+    return LLVM::FCmpPredicate::one;
+  case llvm::CmpInst::Predicate::FCMP_OLT:
+    return LLVM::FCmpPredicate::olt;
+  case llvm::CmpInst::Predicate::FCMP_OLE:
+    return LLVM::FCmpPredicate::ole;
+  case llvm::CmpInst::Predicate::FCMP_OGT:
+    return LLVM::FCmpPredicate::ogt;
+  case llvm::CmpInst::Predicate::FCMP_OGE:
+    return LLVM::FCmpPredicate::oge;
+  case llvm::CmpInst::Predicate::FCMP_ORD:
+    return LLVM::FCmpPredicate::ord;
+  case llvm::CmpInst::Predicate::FCMP_ULT:
+    return LLVM::FCmpPredicate::ult;
+  case llvm::CmpInst::Predicate::FCMP_ULE:
+    return LLVM::FCmpPredicate::ule;
+  case llvm::CmpInst::Predicate::FCMP_UGT:
+    return LLVM::FCmpPredicate::ugt;
+  case llvm::CmpInst::Predicate::FCMP_UGE:
+    return LLVM::FCmpPredicate::uge;
+  case llvm::CmpInst::Predicate::FCMP_UNO:
+    return LLVM::FCmpPredicate::uno;
+  case llvm::CmpInst::Predicate::FCMP_UEQ:
+    return LLVM::FCmpPredicate::ueq;
+  case llvm::CmpInst::Predicate::FCMP_UNE:
+    return LLVM::FCmpPredicate::une;
+  }
+  llvm_unreachable("incorrect floating point comparison predicate");
 }
 
 static AtomicOrdering getLLVMAtomicOrdering(llvm::AtomicOrdering ordering) {
@@ -774,6 +818,16 @@ LogicalResult Importer::processInstruction(llvm::Instruction *inst) {
         rhs);
     return success();
   }
+  case llvm::Instruction::FCmp: {
+    Value lhs = processValue(inst->getOperand(0));
+    Value rhs = processValue(inst->getOperand(1));
+    if (!lhs || !rhs)
+      return failure();
+    instMap[inst] = b.create<FCmpOp>(
+        loc, b.getI1Type(),
+        getFCmpPredicate(cast<llvm::FCmpInst>(inst)->getPredicate()), lhs, rhs);
+    return success();
+  }
   case llvm::Instruction::Br: {
     auto *brInst = cast<llvm::BranchInst>(inst);
     OperationState state(loc,

diff  --git a/mlir/test/Target/LLVMIR/Import/basic.ll b/mlir/test/Target/LLVMIR/Import/basic.ll
index 46566a93f24bb..8b77c69e0c82b 100644
--- a/mlir/test/Target/LLVMIR/Import/basic.ll
+++ b/mlir/test/Target/LLVMIR/Import/basic.ll
@@ -281,6 +281,62 @@ define void @FPArithmetic(float %a, float %b, double %c, double %d) {
   ret void
 }
 
+; CHECK-LABEL: llvm.func @FPComparison(%arg0: f32, %arg1: f32)
+define void @FPComparison(float %a, float %b) {
+  ; CHECK: llvm.fcmp "_false" %arg0, %arg1
+  %1 = fcmp false float %a, %b
+  ; CHECK: llvm.fcmp "oeq" %arg0, %arg1
+  %2 = fcmp oeq float %a, %b
+  ; CHECK: llvm.fcmp "ogt" %arg0, %arg1
+  %3 = fcmp ogt float %a, %b
+  ; CHECK: llvm.fcmp "oge" %arg0, %arg1
+  %4 = fcmp oge float %a, %b
+  ; CHECK: llvm.fcmp "olt" %arg0, %arg1
+  %5 = fcmp olt float %a, %b
+  ; CHECK: llvm.fcmp "ole" %arg0, %arg1
+  %6 = fcmp ole float %a, %b
+  ; CHECK: llvm.fcmp "one" %arg0, %arg1
+  %7 = fcmp one float %a, %b
+  ; CHECK: llvm.fcmp "ord" %arg0, %arg1
+  %8 = fcmp ord float %a, %b
+  ; CHECK: llvm.fcmp "ueq" %arg0, %arg1
+  %9 = fcmp ueq float %a, %b
+  ; CHECK: llvm.fcmp "ugt" %arg0, %arg1
+  %10 = fcmp ugt float %a, %b
+  ; CHECK: llvm.fcmp "uge" %arg0, %arg1
+  %11 = fcmp uge float %a, %b
+  ; CHECK: llvm.fcmp "ult" %arg0, %arg1
+  %12 = fcmp ult float %a, %b
+  ; CHECK: llvm.fcmp "ule" %arg0, %arg1
+  %13 = fcmp ule float %a, %b
+  ; CHECK: llvm.fcmp "une" %arg0, %arg1
+  %14 = fcmp une float %a, %b
+  ; CHECK: llvm.fcmp "uno" %arg0, %arg1
+  %15 = fcmp uno float %a, %b
+  ; CHECK: llvm.fcmp "_true" %arg0, %arg1
+  %16 = fcmp true float %a, %b
+  ret void
+}
+
+; Testing rest of the floating point constant kinds.
+; CHECK-LABEL: llvm.func @FPConstant(%arg0: f16, %arg1: bf16, %arg2: f128, %arg3: f80)
+define void @FPConstant(half %a, bfloat %b, fp128 %c, x86_fp80 %d) {
+  ; CHECK-DAG: %[[C0:.+]] = llvm.mlir.constant(7.000000e+00 : f80) : f80
+  ; CHECK-DAG: %[[C1:.+]] = llvm.mlir.constant(0.000000e+00 : f128) : f128
+  ; CHECK-DAG: %[[C2:.+]] = llvm.mlir.constant(1.000000e+00 : bf16) : bf16
+  ; CHECK-DAG: %[[C3:.+]] = llvm.mlir.constant(1.000000e+00 : f16) : f16
+
+  ; CHECK: llvm.fadd %[[C3]], %arg0  : f16
+  %1 = fadd half 1.0, %a
+  ; CHECK: llvm.fadd %[[C2]], %arg1  : bf16
+  %2 = fadd bfloat 1.0, %b
+  ; CHECK: llvm.fadd %[[C1]], %arg2  : f128
+  %3 = fadd fp128 0xL00000000000000000000000000000000, %c
+  ; CHECK: llvm.fadd %[[C0]], %arg3  : f80
+  %4 = fadd x86_fp80 0xK4001E000000000000000, %d
+  ret void
+}
+
 ;
 ; Functions as constants.
 ;


        


More information about the Mlir-commits mailing list