[flang-commits] [flang] 39f4ef8 - [fir] Add fir.select_case conversion

Valentin Clement via flang-commits flang-commits at lists.llvm.org
Thu Nov 11 06:01:04 PST 2021


Author: Valentin Clement
Date: 2021-11-11T15:00:51+01:00
New Revision: 39f4ef81463d66779ea3430bd3a95284fe34b6bf

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

LOG: [fir] Add fir.select_case conversion

The `fir.select_case` operation is converted to a if-then-else ladder.

Conversion of `fir.select_case` operation with character is not
implemented yet.

This patch is part of the upstreaming effort from fir-dev branch.

Reviewed By: kiranchandramohan, mehdi_amini

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

Co-authored-by: Eric Schweitz <eschweitz at nvidia.com>

Added: 
    

Modified: 
    flang/include/flang/Optimizer/Dialect/FIROps.td
    flang/lib/Optimizer/CodeGen/CodeGen.cpp
    flang/lib/Optimizer/Dialect/FIROps.cpp
    flang/test/Fir/convert-to-llvm-invalid.fir
    flang/test/Fir/convert-to-llvm.fir

Removed: 
    


################################################################################
diff  --git a/flang/include/flang/Optimizer/Dialect/FIROps.td b/flang/include/flang/Optimizer/Dialect/FIROps.td
index 0be585fc9d38..57109bcada9f 100644
--- a/flang/include/flang/Optimizer/Dialect/FIROps.td
+++ b/flang/include/flang/Optimizer/Dialect/FIROps.td
@@ -498,6 +498,8 @@ class fir_SwitchTerminatorOp<string mnemonic, list<OpTrait> traits = []> :
     llvm::Optional<mlir::OperandRange> getCompareOperands(unsigned cond);
     llvm::Optional<llvm::ArrayRef<mlir::Value>> getCompareOperands(
         llvm::ArrayRef<mlir::Value> operands, unsigned cond);
+    llvm::Optional<mlir::ValueRange> getCompareOperands(
+        mlir::ValueRange operands, unsigned cond);
 
     llvm::Optional<llvm::ArrayRef<mlir::Value>> getSuccessorOperands(
         llvm::ArrayRef<mlir::Value> operands, unsigned cond);

diff  --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
index 4e20d3d0c9ef..fe43d2e8f190 100644
--- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp
+++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
@@ -13,6 +13,7 @@
 #include "flang/Optimizer/CodeGen/CodeGen.h"
 #include "PassDetail.h"
 #include "flang/ISO_Fortran_binding.h"
+#include "flang/Optimizer/Dialect/FIRAttr.h"
 #include "flang/Optimizer/Dialect/FIROps.h"
 #include "mlir/Conversion/ArithmeticToLLVM/ArithmeticToLLVM.h"
 #include "mlir/Conversion/LLVMCommon/Pattern.h"
@@ -40,6 +41,13 @@ genConstantIndex(mlir::Location loc, mlir::Type ity,
   return rewriter.create<mlir::LLVM::ConstantOp>(loc, ity, cattr);
 }
 
+static Block *createBlock(mlir::ConversionPatternRewriter &rewriter,
+                          mlir::Block *insertBefore) {
+  assert(insertBefore && "expected valid insertion block");
+  return rewriter.createBlock(insertBefore->getParent(),
+                              mlir::Region::iterator(insertBefore));
+}
+
 namespace {
 /// FIR conversion pattern template
 template <typename FromOp>
@@ -695,6 +703,122 @@ struct GlobalOpConversion : public FIROpConversion<fir::GlobalOp> {
   }
 };
 
+void genCondBrOp(mlir::Location loc, mlir::Value cmp, mlir::Block *dest,
+                 Optional<mlir::ValueRange> destOps,
+                 mlir::ConversionPatternRewriter &rewriter,
+                 mlir::Block *newBlock) {
+  if (destOps.hasValue())
+    rewriter.create<mlir::LLVM::CondBrOp>(loc, cmp, dest, destOps.getValue(),
+                                          newBlock, mlir::ValueRange());
+  else
+    rewriter.create<mlir::LLVM::CondBrOp>(loc, cmp, dest, newBlock);
+}
+
+template <typename A, typename B>
+void genBrOp(A caseOp, mlir::Block *dest, Optional<B> destOps,
+             mlir::ConversionPatternRewriter &rewriter) {
+  if (destOps.hasValue())
+    rewriter.replaceOpWithNewOp<mlir::LLVM::BrOp>(caseOp, destOps.getValue(),
+                                                  dest);
+  else
+    rewriter.replaceOpWithNewOp<mlir::LLVM::BrOp>(caseOp, llvm::None, dest);
+}
+
+void genCaseLadderStep(mlir::Location loc, mlir::Value cmp, mlir::Block *dest,
+                       Optional<mlir::ValueRange> destOps,
+                       mlir::ConversionPatternRewriter &rewriter) {
+  auto *thisBlock = rewriter.getInsertionBlock();
+  auto *newBlock = createBlock(rewriter, dest);
+  rewriter.setInsertionPointToEnd(thisBlock);
+  genCondBrOp(loc, cmp, dest, destOps, rewriter, newBlock);
+  rewriter.setInsertionPointToEnd(newBlock);
+}
+
+/// Conversion of `fir.select_case`
+///
+/// The `fir.select_case` operation is converted to a if-then-else ladder.
+/// Depending on the case condition type, one or several comparison and
+/// conditional branching can be generated.
+///
+/// A a point value case such as `case(4)`, a lower bound case such as
+/// `case(5:)` or an upper bound case such as `case(:3)` are converted to a
+/// simple comparison between the selector value and the constant value in the
+/// case. The block associated with the case condition is then executed if
+/// the comparison succeed otherwise it branch to the next block with the
+/// comparison for the the next case conditon.
+///
+/// A closed interval case condition such as `case(7:10)` is converted with a
+/// first comparison and conditional branching for the lower bound. If
+/// successful, it branch to a second block with the comparison for the
+/// upper bound in the same case condition.
+///
+/// TODO: lowering of CHARACTER type cases is not handled yet.
+struct SelectCaseOpConversion : public FIROpConversion<fir::SelectCaseOp> {
+  using FIROpConversion::FIROpConversion;
+
+  mlir::LogicalResult
+  matchAndRewrite(fir::SelectCaseOp caseOp, OpAdaptor adaptor,
+                  mlir::ConversionPatternRewriter &rewriter) const override {
+    unsigned conds = caseOp.getNumConditions();
+    llvm::ArrayRef<mlir::Attribute> cases = caseOp.getCases().getValue();
+    // Type can be CHARACTER, INTEGER, or LOGICAL (C1145)
+    LLVM_ATTRIBUTE_UNUSED auto ty = caseOp.getSelector().getType();
+    if (ty.isa<fir::CharacterType>())
+      return rewriter.notifyMatchFailure(caseOp,
+                                         "conversion of fir.select_case with "
+                                         "character type not implemented yet");
+    mlir::Value selector = caseOp.getSelector(adaptor.getOperands());
+    auto loc = caseOp.getLoc();
+    for (unsigned t = 0; t != conds; ++t) {
+      mlir::Block *dest = caseOp.getSuccessor(t);
+      llvm::Optional<mlir::ValueRange> destOps =
+          caseOp.getSuccessorOperands(adaptor.getOperands(), t);
+      llvm::Optional<mlir::ValueRange> cmpOps =
+          *caseOp.getCompareOperands(adaptor.getOperands(), t);
+      mlir::Value caseArg = *(cmpOps.getValue().begin());
+      mlir::Attribute attr = cases[t];
+      if (attr.isa<fir::PointIntervalAttr>()) {
+        auto cmp = rewriter.create<mlir::LLVM::ICmpOp>(
+            loc, mlir::LLVM::ICmpPredicate::eq, selector, caseArg);
+        genCaseLadderStep(loc, cmp, dest, destOps, rewriter);
+        continue;
+      }
+      if (attr.isa<fir::LowerBoundAttr>()) {
+        auto cmp = rewriter.create<mlir::LLVM::ICmpOp>(
+            loc, mlir::LLVM::ICmpPredicate::sle, caseArg, selector);
+        genCaseLadderStep(loc, cmp, dest, destOps, rewriter);
+        continue;
+      }
+      if (attr.isa<fir::UpperBoundAttr>()) {
+        auto cmp = rewriter.create<mlir::LLVM::ICmpOp>(
+            loc, mlir::LLVM::ICmpPredicate::sle, selector, caseArg);
+        genCaseLadderStep(loc, cmp, dest, destOps, rewriter);
+        continue;
+      }
+      if (attr.isa<fir::ClosedIntervalAttr>()) {
+        auto cmp = rewriter.create<mlir::LLVM::ICmpOp>(
+            loc, mlir::LLVM::ICmpPredicate::sle, caseArg, selector);
+        auto *thisBlock = rewriter.getInsertionBlock();
+        auto *newBlock1 = createBlock(rewriter, dest);
+        auto *newBlock2 = createBlock(rewriter, dest);
+        rewriter.setInsertionPointToEnd(thisBlock);
+        rewriter.create<mlir::LLVM::CondBrOp>(loc, cmp, newBlock1, newBlock2);
+        rewriter.setInsertionPointToEnd(newBlock1);
+        mlir::Value caseArg0 = *(cmpOps.getValue().begin() + 1);
+        auto cmp0 = rewriter.create<mlir::LLVM::ICmpOp>(
+            loc, mlir::LLVM::ICmpPredicate::sle, selector, caseArg0);
+        genCondBrOp(loc, cmp0, dest, destOps, rewriter, newBlock2);
+        rewriter.setInsertionPointToEnd(newBlock2);
+        continue;
+      }
+      assert(attr.isa<mlir::UnitAttr>());
+      assert((t + 1 == conds) && "unit must be last");
+      genBrOp(caseOp, dest, destOps, rewriter);
+    }
+    return success();
+  }
+};
+
 template <typename OP>
 void selectMatchAndRewrite(fir::LLVMTypeConverter &lowering, OP select,
                            typename OP::Adaptor adaptor,
@@ -1233,9 +1357,9 @@ class FIRToLLVMLowering : public fir::FIRToLLVMLoweringBase<FIRToLLVMLowering> {
         DivcOpConversion, ExtractValueOpConversion, HasValueOpConversion,
         GlobalOpConversion, InsertOnRangeOpConversion, InsertValueOpConversion,
         LoadOpConversion, NegcOpConversion, MulcOpConversion,
-        SelectOpConversion, SelectRankOpConversion, StoreOpConversion,
-        SubcOpConversion, UndefOpConversion, UnreachableOpConversion,
-        ZeroOpConversion>(typeConverter);
+        SelectCaseOpConversion, SelectOpConversion, SelectRankOpConversion,
+        StoreOpConversion, SubcOpConversion, UndefOpConversion,
+        UnreachableOpConversion, ZeroOpConversion>(typeConverter);
     mlir::populateStdToLLVMConversionPatterns(typeConverter, pattern);
     mlir::arith::populateArithmeticToLLVMConversionPatterns(typeConverter,
                                                             pattern);

diff  --git a/flang/lib/Optimizer/Dialect/FIROps.cpp b/flang/lib/Optimizer/Dialect/FIROps.cpp
index dab873809bcf..2e30d1e9afce 100644
--- a/flang/lib/Optimizer/Dialect/FIROps.cpp
+++ b/flang/lib/Optimizer/Dialect/FIROps.cpp
@@ -2297,6 +2297,16 @@ fir::SelectCaseOp::getCompareOperands(llvm::ArrayRef<mlir::Value> operands,
   return {getSubOperands(cond, getSubOperands(1, operands, segments), a)};
 }
 
+llvm::Optional<mlir::ValueRange>
+fir::SelectCaseOp::getCompareOperands(mlir::ValueRange operands,
+                                      unsigned cond) {
+  auto a = (*this)->getAttrOfType<mlir::DenseIntElementsAttr>(
+      getCompareOffsetAttr());
+  auto segments = (*this)->getAttrOfType<mlir::DenseIntElementsAttr>(
+      getOperandSegmentSizeAttr());
+  return {getSubOperands(cond, getSubOperands(1, operands, segments), a)};
+}
+
 llvm::Optional<mlir::MutableOperandRange>
 fir::SelectCaseOp::getMutableSuccessorOperands(unsigned oper) {
   return ::getMutableSuccessorOperands(oper, targetArgsMutable(),
@@ -2313,6 +2323,16 @@ fir::SelectCaseOp::getSuccessorOperands(llvm::ArrayRef<mlir::Value> operands,
   return {getSubOperands(oper, getSubOperands(2, operands, segments), a)};
 }
 
+llvm::Optional<mlir::ValueRange>
+fir::SelectCaseOp::getSuccessorOperands(mlir::ValueRange operands,
+                                        unsigned oper) {
+  auto a =
+      (*this)->getAttrOfType<mlir::DenseIntElementsAttr>(getTargetOffsetAttr());
+  auto segments = (*this)->getAttrOfType<mlir::DenseIntElementsAttr>(
+      getOperandSegmentSizeAttr());
+  return {getSubOperands(oper, getSubOperands(2, operands, segments), a)};
+}
+
 // parser for fir.select_case Op
 static mlir::ParseResult parseSelectCase(mlir::OpAsmParser &parser,
                                          mlir::OperationState &result) {

diff  --git a/flang/test/Fir/convert-to-llvm-invalid.fir b/flang/test/Fir/convert-to-llvm-invalid.fir
index c56168002e9f..c219111817e6 100644
--- a/flang/test/Fir/convert-to-llvm-invalid.fir
+++ b/flang/test/Fir/convert-to-llvm-invalid.fir
@@ -2,6 +2,9 @@
 
 // RUN: fir-opt --split-input-file --fir-to-llvm-ir="target=x86_64-unknown-linux-gnu" --verify-diagnostics %s
 
+// Test `fir.zero` conversion failure with aggregate type.
+// Not implemented yet.
+
 func @zero_aggregate() {
   // expected-error at +1{{failed to legalize operation 'fir.zero_bits'}}
   %a = fir.zero_bits !fir.array<10xf32>
@@ -27,3 +30,23 @@ func @dispatch(%arg0: !fir.box<!fir.type<derived3{f:f32}>>) {
 fir.dispatch_table @dispatch_tbl {
   fir.dt_entry "method", @method_impl
 }
+
+// -----
+
+// Test `fir.select_case` conversion failure with character type.
+// Not implemented yet.
+
+func @select_case_charachter(%arg0: !fir.char<2, 10>, %arg1: !fir.char<2, 10>, %arg2: !fir.char<2, 10>) {
+  // expected-error at +1{{failed to legalize operation 'fir.select_case'}}
+  fir.select_case %arg0 : !fir.char<2, 10> [#fir.point, %arg1, ^bb1,
+                                            #fir.point, %arg2, ^bb2,
+                                            unit, ^bb3]
+^bb1:
+  %c1_i32 = arith.constant 1 : i32
+  br ^bb3
+^bb2:
+  %c2_i32 = arith.constant 2 : i32
+  br ^bb3
+^bb3:
+  return
+}

diff  --git a/flang/test/Fir/convert-to-llvm.fir b/flang/test/Fir/convert-to-llvm.fir
index 08621052051e..2fd748422207 100644
--- a/flang/test/Fir/convert-to-llvm.fir
+++ b/flang/test/Fir/convert-to-llvm.fir
@@ -961,3 +961,155 @@ func @alloca_array_with_holes(%0 : index, %1 : index) -> !fir.ref<!fir.array<4x?
 // CHECK: [[PROD3:%.*]] = llvm.mul [[PROD2]], [[B]] : i64
 // CHECK: [[RES:%.*]] = llvm.alloca [[PROD3]] x i32 {in_type = !fir.array<4x?x3x?x5xi32>
 // CHECK: llvm.return [[RES]] : !llvm.ptr<i32>
+
+// -----
+
+// Test `fir.select_case` operation conversion with INTEGER.
+
+func @select_case_integer(%arg0: !fir.ref<i32>) -> i32 {
+  %2 = fir.load %arg0 : !fir.ref<i32>
+  %c1_i32 = arith.constant 1 : i32
+  %c2_i32 = arith.constant 2 : i32
+  %c4_i32 = arith.constant 4 : i32
+  %c5_i32 = arith.constant 5 : i32
+  %c7_i32 = arith.constant 7 : i32
+  %c8_i32 = arith.constant 8 : i32
+  %c15_i32 = arith.constant 15 : i32
+  %c21_i32 = arith.constant 21 : i32
+  fir.select_case %2 : i32 [#fir.upper, %c1_i32, ^bb1,
+                            #fir.point, %c2_i32, ^bb2,
+                            #fir.interval, %c4_i32, %c5_i32, ^bb4,
+                            #fir.point, %c7_i32, ^bb5,
+                            #fir.interval, %c8_i32, %c15_i32, ^bb5,
+                            #fir.lower, %c21_i32, ^bb5,
+                            unit, ^bb3]
+^bb1:  // pred: ^bb0
+  %c1_i32_0 = arith.constant 1 : i32
+  fir.store %c1_i32_0 to %arg0 : !fir.ref<i32>
+  br ^bb6
+^bb2:  // pred: ^bb0
+  %c2_i32_1 = arith.constant 2 : i32
+  fir.store %c2_i32_1 to %arg0 : !fir.ref<i32>
+  br ^bb6
+^bb3:  // pred: ^bb0
+  %c0_i32 = arith.constant 0 : i32
+  fir.store %c0_i32 to %arg0 : !fir.ref<i32>
+  br ^bb6
+^bb4:  // pred: ^bb0
+  %c4_i32_2 = arith.constant 4 : i32
+  fir.store %c4_i32_2 to %arg0 : !fir.ref<i32>
+  br ^bb6
+^bb5:  // 3 preds: ^bb0, ^bb0, ^bb0
+  %c7_i32_3 = arith.constant 7 : i32
+  fir.store %c7_i32_3 to %arg0 : !fir.ref<i32>
+  br ^bb6
+^bb6:  // 5 preds: ^bb1, ^bb2, ^bb3, ^bb4, ^bb5
+  %3 = fir.load %arg0 : !fir.ref<i32>
+  return %3 : i32
+}
+
+// CHECK-LABEL: llvm.func @select_case_integer(
+// CHECK-SAME:                         %[[ARG0:.*]]: !llvm.ptr<i32>) -> i32 {
+// CHECK:         %[[SELECT_VALUE:.*]] = llvm.load %[[ARG0]] : !llvm.ptr<i32>
+// CHECK:         %[[CST1:.*]] = llvm.mlir.constant(1 : i32) : i32
+// CHECK:         %[[CST2:.*]] = llvm.mlir.constant(2 : i32) : i32
+// CHECK:         %[[CST4:.*]] = llvm.mlir.constant(4 : i32) : i32
+// CHECK:         %[[CST5:.*]] = llvm.mlir.constant(5 : i32) : i32
+// CHECK:         %[[CST7:.*]] = llvm.mlir.constant(7 : i32) : i32
+// CHECK:         %[[CST8:.*]] = llvm.mlir.constant(8 : i32) : i32
+// CHECK:         %[[CST15:.*]] = llvm.mlir.constant(15 : i32) : i32
+// CHECK:         %[[CST21:.*]] = llvm.mlir.constant(21 : i32) : i32
+// Check for upper bound `case (:1)`
+// CHECK:         %[[CMP_SLE:.*]] = llvm.icmp "sle" %[[SELECT_VALUE]], %[[CST1]] : i32
+// CHECK:         llvm.cond_br %[[CMP_SLE]], ^bb2, ^bb1
+// CHECK-LABEL: ^bb1:
+// Check for point value `case (2)`
+// CHECK:         %[[CMP_EQ:.*]] = llvm.icmp "eq" %[[SELECT_VALUE]], %[[CST2]] : i32
+// CHECK:         llvm.cond_br %[[CMP_EQ]], ^bb4, ^bb3
+// Block ^bb1 in original FIR code.
+// CHECK-LABEL: ^bb2:
+// CHECK:         llvm.br ^bb{{.*}}
+// CHECK-LABEL: ^bb3:
+// Check for the lower bound for the interval `case (4:5)`
+// CHECK:        %[[CMP_SLE:.*]] = llvm.icmp "sle" %[[CST4]], %[[SELECT_VALUE]] : i32
+// CHECK:        llvm.cond_br %[[CMP_SLE]], ^bb[[UPPERBOUND5:.*]], ^bb7
+// Block ^bb2 in original FIR code.
+// CHECK-LABEL: ^bb4:
+// CHECK:        llvm.br ^bb{{.*}}
+// Block ^bb3 in original FIR code.
+// CHECK-LABEL: ^bb5:
+// CHECK:        llvm.br ^bb{{.*}}
+// CHECK:       ^bb[[UPPERBOUND5]]:
+// Check for the upper bound for the interval `case (4:5)`
+// CHECK:        %[[CMP_SLE:.*]] = llvm.icmp "sle" %[[SELECT_VALUE]], %[[CST5]] : i32
+// CHECK:        llvm.cond_br %[[CMP_SLE]], ^bb8, ^bb7
+// CHECK-LABEL: ^bb7:
+// Check for the point value 7 in `case (7,8:15,21:)`
+// CHECK: %[[CMP_EQ:.*]] = llvm.icmp "eq" %[[SELECT_VALUE]], %[[CST7]] : i32
+// CHECK: llvm.cond_br %[[CMP_EQ]], ^bb13, ^bb9
+// Block ^bb4 in original FIR code.
+// CHECK-LABEL: ^bb8:
+// CHECK:        llvm.br ^bb{{.*}}
+// CHECK-LABEL: ^bb9:
+// Check for lower bound 8 in `case (7,8:15,21:)`
+// CHECK:        %[[CMP_SLE:.*]] = llvm.icmp "sle" %[[CST8]], %[[SELECT_VALUE]] : i32
+// CHECK:        llvm.cond_br %[[CMP_SLE]], ^bb[[INTERVAL8_15:.*]], ^bb11
+// CHECK:       ^bb[[INTERVAL8_15]]:
+// Check for upper bound 15 in `case (7,8:15,21:)`
+// CHECK:        %[[CMP_SLE:.*]] = llvm.icmp "sle" %[[SELECT_VALUE]], %[[CST15]] : i32
+// CHECK:        llvm.cond_br %[[CMP_SLE]], ^bb13, ^bb11
+// CHECK-LABEL: ^bb11:
+// Check for lower bound 21 in `case (7,8:15,21:)`
+// CHECK:        %[[CMP_SLE:.*]]  = llvm.icmp "sle" %[[CST21]], %[[SELECT_VALUE]] : i32
+// CHECK:        llvm.cond_br %[[CMP_SLE]], ^bb13, ^bb12
+// CHECK-LABEL: ^bb12:
+// CHECK:         llvm.br ^bb5
+// Block ^bb5 in original FIR code.
+// CHECK-LABEL: ^bb13:
+// CHECK:        llvm.br ^bb14
+// Block ^bb6 in original FIR code.
+// CHECK-LABEL: ^bb14:
+// CHECK:        %[[RET:.*]] = llvm.load %[[ARG0:.*]] : !llvm.ptr<i32>
+// CHECK:        llvm.return %[[RET]] : i32
+
+// -----
+
+// Test `fir.select_case` operation conversion with LOGICAL.
+
+func @select_case_logical(%arg0: !fir.ref<!fir.logical<4>>) {
+  %1 = fir.load %arg0 : !fir.ref<!fir.logical<4>>
+  %2 = fir.convert %1 : (!fir.logical<4>) -> i1
+  %false = arith.constant false
+  %true = arith.constant true
+  fir.select_case %2 : i1 [#fir.point, %false, ^bb1,
+                           #fir.point, %true, ^bb2,
+                            unit, ^bb3]
+^bb1:
+  %c1_i32 = arith.constant 1 : i32
+  br ^bb3
+^bb2:
+  %c2_i32 = arith.constant 2 : i32
+  br ^bb3
+^bb3:
+  return
+}
+
+// CHECK-LABEL: llvm.func @select_case_logical(
+// CHECK-SAME:                                 %[[ARG0:.*]]: !llvm.ptr<i32>
+// CHECK:         %[[LOAD_ARG0:.*]] = llvm.load %[[ARG0]] : !llvm.ptr<i32>
+// CHECK:         %[[SELECT_VALUE:.*]] = llvm.trunc %[[LOAD_ARG0]] : i32 to i1
+// CHECK:         %[[CST_FALSE:.*]] = llvm.mlir.constant(false) : i1
+// CHECK:         %[[CST_TRUE:.*]] = llvm.mlir.constant(true) : i1
+// CHECK:         %[[CMPEQ:.*]] = llvm.icmp "eq" %[[SELECT_VALUE]], %[[CST_FALSE]] : i1
+// CHECK:         llvm.cond_br %[[CMPEQ]], ^bb2, ^bb1
+// CHECK-LABEL: ^bb1:
+// CHECK:         %[[CMPEQ:.*]] = llvm.icmp "eq" %[[SELECT_VALUE]], %[[CST_TRUE]] : i1
+// CHECK:         llvm.cond_br %[[CMPEQ]], ^bb4, ^bb3
+// CHECK-LABEL: ^bb2:
+// CHECK:         llvm.br ^bb5
+// CHECK-LABEL: ^bb3:
+// CHECK:         llvm.br ^bb5
+// CHECK-LABEL: ^bb4:
+// CHECK:         llvm.br ^bb5
+// CHECK-LABEL: ^bb5:
+// CHECK:        llvm.return


        


More information about the flang-commits mailing list