Commit 929988b9 authored by Mccaskey, Alex's avatar Mccaskey, Alex
Browse files

fix for bug #189, invalid division of non-matching integer types

parent cf927e1e
Loading
Loading
Loading
Loading
Loading
+10 −30
Original line number Diff line number Diff line
@@ -695,39 +695,19 @@ antlrcpp::Any qasm3_expression_generator::visitMultiplicativeExpression(
        } else if (!rhs.getType().isa<mlir::FloatType>()) {
          rhs = builder.create<mlir::SIToFPOp>(location, rhs, lhs.getType());
        }

        // if (!lhs.getType().isa<mlir::FloatType>()) {
        //   if (auto op = lhs.getDefiningOp<mlir::ConstantOp>()) {
        //     auto value = op.getValue()
        //                      .cast<mlir::IntegerAttr>()
        //                      .getValue()
        //                      .getLimitedValue();
        //     lhs = builder.create<mlir::ConstantOp>(
        //         location, mlir::FloatAttr::get(rhs.getType(),
        //         (double)value));
        //   } else {
        //     printErrorMessage(
        //         "Must cast lhs to float, but it is not constant.");
        //   }
        // } else if (!rhs.getType().isa<mlir::FloatType>()) {
        //   if (auto op = rhs.getDefiningOp<mlir::ConstantOp>()) {
        //     auto value = op.getValue()
        //                      .cast<mlir::IntegerAttr>()
        //                      .getValue()
        //                      .getLimitedValue();
        //     rhs = builder.create<mlir::ConstantOp>(
        //         location, mlir::FloatAttr::get(lhs.getType(),
        //         (double)value));
        //   } else {
        //     printErrorMessage(
        //         "Must cast rhs to float, but it is not constant.", ctx, {lhs,
        //         rhs});
        //   }
        // }

        createOp<mlir::DivFOp>(location, lhs, rhs);
      } else if (lhs.getType().isa<mlir::IntegerType>() &&
                 rhs.getType().isa<mlir::IntegerType>()) {
        
        if (lhs.getType().getIntOrFloatBitWidth() <
            rhs.getType().getIntOrFloatBitWidth()) {
          lhs =
              builder.create<mlir::ZeroExtendIOp>(location, lhs, rhs.getType());
        } else if (rhs.getType().getIntOrFloatBitWidth() <
                   lhs.getType().getIntOrFloatBitWidth()) {
          rhs =
              builder.create<mlir::ZeroExtendIOp>(location, rhs, lhs.getType());
        }
        createOp<mlir::SignedDivIOp>(location, lhs, rhs);
      } else {
        printErrorMessage("Could not perform division, incompatible types: ",
+1 −1
Original line number Diff line number Diff line
@@ -177,7 +177,7 @@ mlir::Type convertQasm3Type(qasm3::qasm3Parser::ClassicalTypeContext* ctx,
    auto start = type.find_first_of("[");
    int64_t bit_size;
    if (start == std::string::npos) {
      bit_size = 32;
      bit_size = type.find("64_t") == std::string::npos ? 32 : 64;
    } else {
      auto finish = type.find_first_of("]");
      auto idx_str = type.substr(start + 1, finish - start - 1);
+12 −1
Original line number Diff line number Diff line
@@ -342,7 +342,18 @@ antlrcpp::Any qasm3_visitor::visitLoopStatement(
        builder.create<mlir::BranchOp>(location, headerBlock);
        builder.setInsertionPointToStart(headerBlock);

        auto load = builder.create<mlir::LoadOp>(location, loop_var_memref);
        mlir::Value load = builder.create<mlir::LoadOp>(location, loop_var_memref);

        if (load.getType().getIntOrFloatBitWidth() <
            b_value.getType().getIntOrFloatBitWidth()) {
          load =
              builder.create<mlir::ZeroExtendIOp>(location, load, b_value.getType());
        } else if (b_value.getType().getIntOrFloatBitWidth() <
                   load.getType().getIntOrFloatBitWidth()) {
          b_value =
              builder.create<mlir::ZeroExtendIOp>(location, b_value, load.getType());
        }

        auto cmp = builder.create<mlir::CmpIOp>(
            location,
            c > 0 ? mlir::CmpIPredicate::slt : mlir::CmpIPredicate::sge, load,
+26 −15
Original line number Diff line number Diff line
@@ -30,26 +30,36 @@ struct MlirGenerationResult {
  MlirGenerationResult(std::unique_ptr<mlir::MLIRContext> &&in_mlir_context,
                       SourceLanguage in_source_language,
                       const std::vector<std::string> &in_unique_function_names,
                       std::unique_ptr<mlir::OwningModuleRef> &&in_module_ref)
                       std::unique_ptr<mlir::OwningModuleRef> &&in_module_ref,
                       bool verbose_error = false)
      : mlir_context(std::move(in_mlir_context)),
        source_language(in_source_language),
        unique_function_names(in_unique_function_names),
        module_ref(std::move(in_module_ref)) {
    // Set the DiagnosticEngine handler
    DiagnosticEngine &engine = (*mlir_context).getDiagEngine();

    // Handle the reported diagnostic.
    // Return success to signal that the diagnostic has either been fully
    // processed, or failure if the diagnostic should be propagated to the
    // previous handlers.
    engine.registerHandler([&](Diagnostic &diag) -> LogicalResult {
      std::cout << "Dumping Module after error.\n";
    engine.registerHandler(
        [&, verbose_error](Diagnostic &diag) -> LogicalResult {
          if (verbose_error) {
            std::cout << "[qcor-mlir] Dumping Module after error.\n";
            (*module_ref)->dump();
          }
          std::string BOLD = "\033[1m";
          std::string RED = "\033[91m";
          std::string CLEAR = "\033[0m";

          for (auto &n : diag.getNotes()) {
            std::string s;
            llvm::raw_string_ostream os(s);
            n.print(os);
            os.flush();
        std::cout << "DiagnosticEngine Note: " << s << "\n";
            std::cout << BOLD << RED << "[qcor-mlir] Reported Error: " << s << "\n"
                      << CLEAR;
          }
          bool should_propagate_diagnostic = true;
          return failure(should_propagate_diagnostic);
@@ -106,7 +116,8 @@ MlirGenerationResult mlir_gen(
               add_entry_point, extra_quantum_args);

  return MlirGenerationResult(std::move(context), src_type,
                              unique_function_names, std::move(module));
                              unique_function_names, std::move(module),
                              extra_quantum_args.count("verbose_error"));
}

MlirGenerationResult mlir_gen(
+42 −21
Original line number Diff line number Diff line
@@ -30,9 +30,12 @@ static cl::opt<std::string> inputFilename(cl::Positional,
                                          cl::init("-"),
                                          cl::value_desc("filename"));

static cl::opt<std::string> qpu("qpu", cl::desc("The quantum coprocessor to compile to."));
static cl::opt<std::string> qrt("qrt", cl::desc("The quantum execution mode: ftqc or nisq."));
static cl::opt<std::string> shots("shots", cl::desc("The number of shots for nisq mode execution."));
static cl::opt<std::string> qpu(
    "qpu", cl::desc("The quantum coprocessor to compile to."));
static cl::opt<std::string> qrt(
    "qrt", cl::desc("The quantum execution mode: ftqc or nisq."));
static cl::opt<std::string> shots(
    "shots", cl::desc("The number of shots for nisq mode execution."));

cl::opt<bool> noEntryPoint("no-entrypoint",
                           cl::desc("Do not add main() to compiled output."));
@@ -44,17 +47,20 @@ cl::opt<bool> mlir_quantum_opt(
cl::opt<std::string> mlir_specified_func_name(
    "internal-func-name", cl::desc("qcor provided function name"));

static cl::opt<bool>
    OptLevelO0("O0", cl::desc("Optimization level 0. Similar to clang -O0. "));
static cl::opt<bool> verbose_error(
    "verbose-error", cl::desc("Printout the full MLIR Module on error."));

static cl::opt<bool>
    OptLevelO1("O1", cl::desc("Optimization level 1. Similar to clang -O1. "));
static cl::opt<bool> OptLevelO0(
    "O0", cl::desc("Optimization level 0. Similar to clang -O0. "));

static cl::opt<bool>
    OptLevelO2("O2", cl::desc("Optimization level 2. Similar to clang -O2. "));
static cl::opt<bool> OptLevelO1(
    "O1", cl::desc("Optimization level 1. Similar to clang -O1. "));

static cl::opt<bool>
    OptLevelO3("O3", cl::desc("Optimization level 3. Similar to clang -O3. "));
static cl::opt<bool> OptLevelO2(
    "O2", cl::desc("Optimization level 2. Similar to clang -O2. "));

static cl::opt<bool> OptLevelO3(
    "O3", cl::desc("Optimization level 3. Similar to clang -O3. "));

namespace {
enum Action { None, DumpMLIR, DumpMLIRLLVM, DumpLLVMIR };
@@ -101,8 +107,12 @@ int main(int argc, char **argv) {
    extra_args.insert({"shots", shots});
  }

  auto mlir_gen_result =
      qcor::util::mlir_gen(inputFilename, !noEntryPoint, input_func_name, extra_args);
  if (verbose_error) {
    extra_args.insert({"verbose_error", ""});
  }

  auto mlir_gen_result = qcor::util::mlir_gen(inputFilename, !noEntryPoint,
                                              input_func_name, extra_args);
  mlir::OwningModuleRef &module = *(mlir_gen_result.module_ref);
  mlir::MLIRContext &context = *(mlir_gen_result.mlir_context);
  std::vector<std::string> &unique_function_names =
@@ -112,6 +122,10 @@ int main(int argc, char **argv) {
  mlir::PassManager pm(&context);
  applyPassManagerCLOptions(pm);

  std::string BOLD = "\033[1m";
  std::string RED = "\033[91m";
  std::string CLEAR = "\033[0m";

  if (qoptimizations) {
    // Add optimization passes
    qcor::configureOptimizationPasses(pm);
@@ -121,7 +135,9 @@ int main(int argc, char **argv) {
    if (qoptimizations) {
      auto module_op = (*module).getOperation();
      if (mlir::failed(pm.run(module_op))) {
        std::cout << "Pass Manager Failed\n";
        std::cout << BOLD << RED
                  << "[qcor-mlir-tool] Language-to-MLIR lowering failed.\n"
                  << CLEAR;
        return 1;
      }
    }
@@ -135,7 +151,9 @@ int main(int argc, char **argv) {

  auto module_op = (*module).getOperation();
  if (mlir::failed(pm.run(module_op))) {
    std::cout << "Pass Manager Failed\n";
    std::cout << BOLD << RED
              << "[qcor-mlir-tool] MLIR-to-LLVM_MLIR lowering failed.\n"
              << CLEAR;
    return 1;
  }

@@ -148,7 +166,9 @@ int main(int argc, char **argv) {
  llvm::LLVMContext llvmContext;
  auto llvmModule = mlir::translateModuleToLLVMIR(*module, llvmContext);
  if (!llvmModule) {
    llvm::errs() << "Failed to emit LLVM IR\n";
    std::cout << BOLD << RED
              << "[qcor-mlir-tool] MLIR_LLVM-to-LLVM_IR lowering failed.\n"
              << CLEAR;
    return -1;
  }
  // Optimize the LLVM IR
@@ -159,7 +179,8 @@ int main(int argc, char **argv) {
  // std::cout << "Opt level: " << optLevel << "\n";
  auto optPipeline = mlir::makeOptimizingTransformer(optLevel, 0, nullptr);
  if (auto err = optPipeline(llvmModule.get())) {
    llvm::errs() << "Failed to optimize LLVM IR " << err << "\n";
    llvm::errs() << BOLD << RED << "Failed to optimize LLVM IR " << err << "\n"
                 << CLEAR;
    return -1;
  }

Loading