[flang-commits] [flang] 96e1d2b - Revert "[Flang] Change fir.divc to perform library call rather than generate inline operations."

Kiran Chandramohan via flang-commits flang-commits at lists.llvm.org
Tue Apr 18 04:22:01 PDT 2023


Author: Kiran Chandramohan
Date: 2023-04-18T11:08:16Z
New Revision: 96e1d2b5b24e7719046df8a199135de33fbd90e3

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

LOG: Revert "[Flang] Change fir.divc to perform library call rather than generate inline operations."

This reverts commit a7bb8e273f433cceeb547e87d04114178573496a.

Revertin since this runs into an ABI issue.

Added: 
    

Modified: 
    flang/lib/Optimizer/CodeGen/CodeGen.cpp
    flang/test/Fir/convert-to-llvm.fir

Removed: 
    


################################################################################
diff  --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
index 862ffd568be45..058cb70a9e78c 100644
--- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp
+++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
@@ -44,7 +44,6 @@
 #include "mlir/Target/LLVMIR/ModuleTranslation.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/TypeSwitch.h"
-#include <mlir/IR/ValueRange.h>
 
 namespace fir {
 #define GEN_PASS_DEF_FIRTOLLVMLOWERING
@@ -3448,87 +3447,42 @@ struct MulcOpConversion : public FIROpConversion<fir::MulcOp> {
   }
 };
 
-static mlir::LogicalResult getDivc3(fir::DivcOp op,
-                                    mlir::ConversionPatternRewriter &rewriter,
-                                    std::string funcName, mlir::Type returnType,
-                                    llvm::SmallVector<mlir::Type> argType,
-                                    llvm::SmallVector<mlir::Value> args) {
-  auto module = op->getParentOfType<mlir::ModuleOp>();
-  auto loc = op.getLoc();
-  if (mlir::LLVM::LLVMFuncOp divideFunc =
-          module.lookupSymbol<mlir::LLVM::LLVMFuncOp>(funcName)) {
-    auto call = rewriter.create<mlir::LLVM::CallOp>(
-        loc, returnType, mlir::SymbolRefAttr::get(divideFunc), args);
-    rewriter.replaceOp(op, call->getResults());
-    return mlir::success();
-  }
-  mlir::OpBuilder moduleBuilder(
-      op->getParentOfType<mlir::ModuleOp>().getBodyRegion());
-  auto divideFunc = moduleBuilder.create<mlir::LLVM::LLVMFuncOp>(
-      rewriter.getUnknownLoc(), funcName,
-      mlir::LLVM::LLVMFunctionType::get(returnType, argType,
-                                        /*isVarArg=*/false));
-  auto call = rewriter.create<mlir::LLVM::CallOp>(
-      loc, returnType, mlir::SymbolRefAttr::get(divideFunc), args);
-  rewriter.replaceOp(op, call->getResults());
-  return mlir::success();
-}
-
-///  complex division
+/// Inlined complex division
 struct DivcOpConversion : public FIROpConversion<fir::DivcOp> {
   using FIROpConversion::FIROpConversion;
 
   mlir::LogicalResult
   matchAndRewrite(fir::DivcOp divc, OpAdaptor adaptor,
                   mlir::ConversionPatternRewriter &rewriter) const override {
+    // TODO: Can we use a call to __divdc3 instead?
+    // Just generate inline code for now.
     // given: (x + iy) / (x' + iy')
     // result: ((xx'+yy')/d) + i((yx'-xy')/d) where d = x'x' + y'y'
     mlir::Value a = adaptor.getOperands()[0];
     mlir::Value b = adaptor.getOperands()[1];
     auto loc = divc.getLoc();
     mlir::Type eleTy = convertType(getComplexEleTy(divc.getType()));
-    llvm::SmallVector<mlir::Type> argTy = {eleTy, eleTy, eleTy, eleTy};
-    mlir::Type firReturnTy = divc.getType();
-    mlir::Type ty = convertType(firReturnTy);
+    mlir::Type ty = convertType(divc.getType());
     auto x0 = rewriter.create<mlir::LLVM::ExtractValueOp>(loc, a, 0);
     auto y0 = rewriter.create<mlir::LLVM::ExtractValueOp>(loc, a, 1);
     auto x1 = rewriter.create<mlir::LLVM::ExtractValueOp>(loc, b, 0);
     auto y1 = rewriter.create<mlir::LLVM::ExtractValueOp>(loc, b, 1);
-
-    fir::KindTy kind = (firReturnTy.dyn_cast<fir::ComplexType>()).getFKind();
-    mlir::SmallVector<mlir::Value> args = {x0, y0, x1, y1};
-    switch (kind) {
-    default:
-      llvm_unreachable("Unsupported complex type");
-    case 4:
-      return getDivc3(divc, rewriter, "__divsc3", ty, argTy, args);
-    case 8:
-      return getDivc3(divc, rewriter, "__divdc3", ty, argTy, args);
-    case 10:
-      return getDivc3(divc, rewriter, "__divxc3", ty, argTy, args);
-    case 16:
-      return getDivc3(divc, rewriter, "__divtc3", ty, argTy, args);
-    case 3:
-    case 2:
-      // No library function for bfloat or half in compiler_rt, generate
-      // inline instead
-      auto xx = rewriter.create<mlir::LLVM::FMulOp>(loc, eleTy, x0, x1);
-      auto x1x1 = rewriter.create<mlir::LLVM::FMulOp>(loc, eleTy, x1, x1);
-      auto yx = rewriter.create<mlir::LLVM::FMulOp>(loc, eleTy, y0, x1);
-      auto xy = rewriter.create<mlir::LLVM::FMulOp>(loc, eleTy, x0, y1);
-      auto yy = rewriter.create<mlir::LLVM::FMulOp>(loc, eleTy, y0, y1);
-      auto y1y1 = rewriter.create<mlir::LLVM::FMulOp>(loc, eleTy, y1, y1);
-      auto d = rewriter.create<mlir::LLVM::FAddOp>(loc, eleTy, x1x1, y1y1);
-      auto rrn = rewriter.create<mlir::LLVM::FAddOp>(loc, eleTy, xx, yy);
-      auto rin = rewriter.create<mlir::LLVM::FSubOp>(loc, eleTy, yx, xy);
-      auto rr = rewriter.create<mlir::LLVM::FDivOp>(loc, eleTy, rrn, d);
-      auto ri = rewriter.create<mlir::LLVM::FDivOp>(loc, eleTy, rin, d);
-      auto ra = rewriter.create<mlir::LLVM::UndefOp>(loc, ty);
-      auto r1 = rewriter.create<mlir::LLVM::InsertValueOp>(loc, ra, rr, 0);
-      auto r0 = rewriter.create<mlir::LLVM::InsertValueOp>(loc, r1, ri, 1);
-      rewriter.replaceOp(divc, r0.getResult());
-      return mlir::success();
-    }
+    auto xx = rewriter.create<mlir::LLVM::FMulOp>(loc, eleTy, x0, x1);
+    auto x1x1 = rewriter.create<mlir::LLVM::FMulOp>(loc, eleTy, x1, x1);
+    auto yx = rewriter.create<mlir::LLVM::FMulOp>(loc, eleTy, y0, x1);
+    auto xy = rewriter.create<mlir::LLVM::FMulOp>(loc, eleTy, x0, y1);
+    auto yy = rewriter.create<mlir::LLVM::FMulOp>(loc, eleTy, y0, y1);
+    auto y1y1 = rewriter.create<mlir::LLVM::FMulOp>(loc, eleTy, y1, y1);
+    auto d = rewriter.create<mlir::LLVM::FAddOp>(loc, eleTy, x1x1, y1y1);
+    auto rrn = rewriter.create<mlir::LLVM::FAddOp>(loc, eleTy, xx, yy);
+    auto rin = rewriter.create<mlir::LLVM::FSubOp>(loc, eleTy, yx, xy);
+    auto rr = rewriter.create<mlir::LLVM::FDivOp>(loc, eleTy, rrn, d);
+    auto ri = rewriter.create<mlir::LLVM::FDivOp>(loc, eleTy, rin, d);
+    auto ra = rewriter.create<mlir::LLVM::UndefOp>(loc, ty);
+    auto r1 = rewriter.create<mlir::LLVM::InsertValueOp>(loc, ra, rr, 0);
+    auto r0 = rewriter.create<mlir::LLVM::InsertValueOp>(loc, r1, ri, 1);
+    rewriter.replaceOp(divc, r0.getResult());
+    return mlir::success();
   }
 };
 

diff  --git a/flang/test/Fir/convert-to-llvm.fir b/flang/test/Fir/convert-to-llvm.fir
index 866d8ebe08d98..d1d62027515e0 100644
--- a/flang/test/Fir/convert-to-llvm.fir
+++ b/flang/test/Fir/convert-to-llvm.fir
@@ -586,42 +586,22 @@ func.func @fir_complex_div(%a: !fir.complex<16>, %b: !fir.complex<16>) -> !fir.c
 // CHECK:         %[[Y0:.*]] = llvm.extractvalue %[[ARG0]][1] : !llvm.struct<(f128, f128)>
 // CHECK:         %[[X1:.*]] = llvm.extractvalue %[[ARG1]][0] : !llvm.struct<(f128, f128)>
 // CHECK:         %[[Y1:.*]] = llvm.extractvalue %[[ARG1]][1] : !llvm.struct<(f128, f128)>
-// CHECK:         %[[CALL:.*]] = llvm.call @__divtc3(%[[X0]], %[[Y0]], %[[X1]], %[[Y1]]) : (f128, f128, f128, f128) -> !llvm.struct<(f128, f128)>
+// CHECK:         %[[MUL_X0_X1:.*]] = llvm.fmul %[[X0]], %[[X1]]  : f128
+// CHECK:         %[[MUL_X1_X1:.*]] = llvm.fmul %[[X1]], %[[X1]]  : f128
+// CHECK:         %[[MUL_Y0_X1:.*]] = llvm.fmul %[[Y0]], %[[X1]]  : f128
+// CHECK:         %[[MUL_X0_Y1:.*]] = llvm.fmul %[[X0]], %[[Y1]]  : f128
+// CHECK:         %[[MUL_Y0_Y1:.*]] = llvm.fmul %[[Y0]], %[[Y1]]  : f128
+// CHECK:         %[[MUL_Y1_Y1:.*]] = llvm.fmul %[[Y1]], %[[Y1]]  : f128
+// CHECK:         %[[ADD_X1X1_Y1Y1:.*]] = llvm.fadd %[[MUL_X1_X1]], %[[MUL_Y1_Y1]]  : f128
+// CHECK:         %[[ADD_X0X1_Y0Y1:.*]] = llvm.fadd %[[MUL_X0_X1]], %[[MUL_Y0_Y1]]  : f128
+// CHECK:         %[[SUB_Y0X1_X0Y1:.*]] = llvm.fsub %[[MUL_Y0_X1]], %[[MUL_X0_Y1]]  : f128
+// CHECK:         %[[DIV0:.*]] = llvm.fdiv %[[ADD_X0X1_Y0Y1]], %[[ADD_X1X1_Y1Y1]]  : f128
+// CHECK:         %[[DIV1:.*]] = llvm.fdiv %[[SUB_Y0X1_X0Y1]], %[[ADD_X1X1_Y1Y1]]  : f128
+// CHECK:         %{{.*}} = llvm.mlir.undef : !llvm.struct<(f128, f128)>
+// CHECK:         %{{.*}} = llvm.insertvalue %[[DIV0]], %{{.*}}[0] : !llvm.struct<(f128, f128)>
+// CHECK:         %{{.*}} = llvm.insertvalue %[[DIV1]], %{{.*}}[1] : !llvm.struct<(f128, f128)>
 // CHECK:         llvm.return %{{.*}} : !llvm.struct<(f128, f128)>
 
-// -----
-
-// Test FIR complex division inlines for KIND=3
-
-func.func @fir_complex_div(%a: !fir.complex<3>, %b: !fir.complex<3>) -> !fir.complex<3> {
-  %c = fir.divc %a, %b : !fir.complex<3>
-  return %c : !fir.complex<3>
-}
-
-// CHECK-LABEL: llvm.func @fir_complex_div(
-// CHECK-SAME:                             %[[ARG0:.*]]: !llvm.struct<(bf16, bf16)>,
-// CHECK-SAME:                             %[[ARG1:.*]]: !llvm.struct<(bf16, bf16)>) -> !llvm.struct<(bf16, bf16)> {
-// CHECK:         %[[X0:.*]] = llvm.extractvalue %[[ARG0]][0] : !llvm.struct<(bf16, bf16)>
-// CHECK:         %[[Y0:.*]] = llvm.extractvalue %[[ARG0]][1] : !llvm.struct<(bf16, bf16)>
-// CHECK:         %[[X1:.*]] = llvm.extractvalue %[[ARG1]][0] : !llvm.struct<(bf16, bf16)>
-// CHECK:         %[[Y1:.*]] = llvm.extractvalue %[[ARG1]][1] : !llvm.struct<(bf16, bf16)>
-// CHECK:         %[[MUL_X0_X1:.*]] = llvm.fmul %[[X0]], %[[X1]]  : bf16
-// CHECK:         %[[MUL_X1_X1:.*]] = llvm.fmul %[[X1]], %[[X1]]  : bf16
-// CHECK:         %[[MUL_Y0_X1:.*]] = llvm.fmul %[[Y0]], %[[X1]]  : bf16
-// CHECK:         %[[MUL_X0_Y1:.*]] = llvm.fmul %[[X0]], %[[Y1]]  : bf16
-// CHECK:         %[[MUL_Y0_Y1:.*]] = llvm.fmul %[[Y0]], %[[Y1]]  : bf16
-// CHECK:         %[[MUL_Y1_Y1:.*]] = llvm.fmul %[[Y1]], %[[Y1]]  : bf16
-// CHECK:         %[[ADD_X1X1_Y1Y1:.*]] = llvm.fadd %[[MUL_X1_X1]], %[[MUL_Y1_Y1]]  : bf16
-// CHECK:         %[[ADD_X0X1_Y0Y1:.*]] = llvm.fadd %[[MUL_X0_X1]], %[[MUL_Y0_Y1]]  : bf16
-// CHECK:         %[[SUB_Y0X1_X0Y1:.*]] = llvm.fsub %[[MUL_Y0_X1]], %[[MUL_X0_Y1]]  : bf16
-// CHECK:         %[[DIV0:.*]] = llvm.fdiv %[[ADD_X0X1_Y0Y1]], %[[ADD_X1X1_Y1Y1]]  : bf16
-// CHECK:         %[[DIV1:.*]] = llvm.fdiv %[[SUB_Y0X1_X0Y1]], %[[ADD_X1X1_Y1Y1]]  : bf16
-// CHECK:         %{{.*}} = llvm.mlir.undef : !llvm.struct<(bf16, bf16)>
-// CHECK:         %{{.*}} = llvm.insertvalue %[[DIV0]], %{{.*}}[0] : !llvm.struct<(bf16, bf16)>
-// CHECK:         %{{.*}} = llvm.insertvalue %[[DIV1]], %{{.*}}[1] : !llvm.struct<(bf16, bf16)>
-// CHECK:         llvm.return %{{.*}} : !llvm.struct<(bf16, bf16)>
-
-
 // -----
 
 // Test FIR complex negation conversion


        


More information about the flang-commits mailing list