diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td @@ -190,8 +190,8 @@ // Other integer operations. def LLVM_ICmpOp : LLVM_Op<"icmp", [NoSideEffect]> { let arguments = (ins ICmpPredicate:$predicate, - LLVM_ScalarOrVectorOf:$lhs, - LLVM_ScalarOrVectorOf:$rhs); + AnyTypeOf<[LLVM_ScalarOrVectorOf, LLVM_ScalarOrVectorOf]>:$lhs, + AnyTypeOf<[LLVM_ScalarOrVectorOf, LLVM_ScalarOrVectorOf]>:$rhs); let results = (outs LLVM_ScalarOrVectorOf:$res); let llvmBuilder = [{ $res = builder.CreateICmp(getLLVMCmpPredicate($predicate), $lhs, $rhs); diff --git a/mlir/include/mlir/Dialect/StandardOps/IR/Ops.td b/mlir/include/mlir/Dialect/StandardOps/IR/Ops.td --- a/mlir/include/mlir/Dialect/StandardOps/IR/Ops.td +++ b/mlir/include/mlir/Dialect/StandardOps/IR/Ops.td @@ -277,6 +277,7 @@ ``` }]; let hasFolder = 1; + let hasCanonicalizer = 1; } //===----------------------------------------------------------------------===// @@ -1249,6 +1250,7 @@ }]; let hasFolder = 1; + let hasCanonicalizer = 1; } //===----------------------------------------------------------------------===// @@ -1711,6 +1713,7 @@ let printer = [{ return printStandardCastOp(this->getOperation(), p); }]; + let hasFolder = 1; } //===----------------------------------------------------------------------===// @@ -1790,6 +1793,7 @@ def SubIOp : IntBinaryOp<"subi"> { let summary = "integer subtraction operation"; let hasFolder = 1; + let hasCanonicalizer = 1; } //===----------------------------------------------------------------------===// @@ -2288,6 +2292,7 @@ ``` }]; let hasFolder = 1; + let hasCanonicalizer = 1; } //===----------------------------------------------------------------------===// diff --git a/mlir/lib/Conversion/StandardToLLVM/StandardToLLVM.cpp b/mlir/lib/Conversion/StandardToLLVM/StandardToLLVM.cpp --- a/mlir/lib/Conversion/StandardToLLVM/StandardToLLVM.cpp +++ b/mlir/lib/Conversion/StandardToLLVM/StandardToLLVM.cpp @@ -1412,9 +1412,11 @@ // Create an LLVM function, use external linkage by default until MLIR // functions have linkage. + LLVM::Linkage linkage = (funcOp.isPublic() || funcOp.isExternal()) + ? LLVM::Linkage::External + : LLVM::Linkage::Private; auto newFuncOp = rewriter.create( - funcOp.getLoc(), funcOp.getName(), llvmType, LLVM::Linkage::External, - attributes); + funcOp.getLoc(), funcOp.getName(), llvmType, linkage, attributes); rewriter.inlineRegionBefore(funcOp.getBody(), newFuncOp.getBody(), newFuncOp.end()); if (failed(rewriter.convertRegionTypes(&newFuncOp.getBody(), *typeConverter, diff --git a/mlir/lib/Dialect/StandardOps/IR/Ops.cpp b/mlir/lib/Dialect/StandardOps/IR/Ops.cpp --- a/mlir/lib/Dialect/StandardOps/IR/Ops.cpp +++ b/mlir/lib/Dialect/StandardOps/IR/Ops.cpp @@ -283,6 +283,73 @@ })); } +/// Canonicalize a sum of a constant and (constant - something) to simply be +/// a sum of constants minus something. This transformation does similar +/// transformations for additions of a constant with a subtract/add of +/// a constant. +struct AddConstantReorder : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + LogicalResult matchAndRewrite(AddIOp addop, + PatternRewriter &rewriter) const override { + for (int i = 0; i < 2; i++) { + if (auto origConstOp = addop.getOperand(i).getDefiningOp()) { + + if (auto midAddOp = addop.getOperand(1 - i).getDefiningOp()) { + for (int j = 0; j < 2; j++) { + if (auto midConstOp = + midAddOp.getOperand(j).getDefiningOp()) { + auto nextConstant = rewriter.create( + addop.getLoc(), + rewriter.getIntegerAttr( + addop.getType(), + origConstOp.getValue().cast().getValue() + + midConstOp.getValue() + .cast() + .getValue())); + rewriter.replaceOpWithNewOp(addop, nextConstant, + midAddOp.getOperand(1 - j)); + return success(); + } + } + } + if (auto midSubOp = addop.getOperand(1 - i).getDefiningOp()) { + if (auto midConstOp = + midSubOp.getOperand(0).getDefiningOp()) { + auto nextConstant = rewriter.create( + addop.getLoc(), + rewriter.getIntegerAttr( + addop.getType(), + origConstOp.getValue().cast().getValue() + + midConstOp.getValue().cast().getValue())); + rewriter.replaceOpWithNewOp(addop, nextConstant, + midSubOp.getOperand(1)); + return success(); + } + if (auto midConstOp = + midSubOp.getOperand(1).getDefiningOp()) { + auto nextConstant = rewriter.create( + addop.getLoc(), + rewriter.getIntegerAttr( + addop.getType(), + origConstOp.getValue().cast().getValue() - + midConstOp.getValue().cast().getValue())); + rewriter.replaceOpWithNewOp(addop, nextConstant, + midSubOp.getOperand(0)); + return success(); + } + } + } + } + return failure(); + } +}; + +void AddIOp::getCanonicalizationPatterns(OwningRewritePatternList &results, + MLIRContext *context) { + results.insert(context); +} + //===----------------------------------------------------------------------===// // AndOp //===----------------------------------------------------------------------===// @@ -930,13 +997,51 @@ return success(); } }; + +struct CondBranchTruthPropagation : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + LogicalResult matchAndRewrite(CondBranchOp condbr, + PatternRewriter &rewriter) const override { + // Check that we have a single distinct predecessor. + bool replaced = false; + mlir::Type ty = rewriter.getI1Type(); + + if (condbr.getTrueDest()->getSinglePredecessor()) { + for (OpOperand &use : + llvm::make_early_inc_range(condbr.condition().getUses())) { + if (use.getOwner()->getBlock() == condbr.getTrueDest()) { + replaced = true; + rewriter.updateRootInPlace(use.getOwner(), [&]() { + use.set(rewriter.create( + condbr.getLoc(), ty, rewriter.getIntegerAttr(ty, 1))); + }); + } + } + } + if (condbr.getFalseDest()->getSinglePredecessor()) { + for (OpOperand &use : + llvm::make_early_inc_range(condbr.condition().getUses())) { + if (use.getOwner()->getBlock() == condbr.getFalseDest()) { + replaced = true; + rewriter.updateRootInPlace(use.getOwner(), [&]() { + use.set(rewriter.create( + condbr.getLoc(), ty, rewriter.getIntegerAttr(ty, 0))); + }); + } + } + } + return replaced ? success() : failure(); + } +}; } // end anonymous namespace void CondBranchOp::getCanonicalizationPatterns(RewritePatternSet &results, MLIRContext *context) { results.add(context); + SimplifyCondBranchFromCondBranchOnSameCondition, + CondBranchTruthPropagation>(context); } Optional @@ -1241,6 +1346,28 @@ return {}; } +namespace { +struct IndexCastOfSExt : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + LogicalResult matchAndRewrite(IndexCastOp op, + PatternRewriter &rewriter) const override { + + if (auto extop = op.getOperand().getDefiningOp()) { + op.setOperand(extop.getOperand()); + return success(); + } + return failure(); + } +}; + +} // namespace + +void IndexCastOp::getCanonicalizationPatterns(OwningRewritePatternList &results, + MLIRContext *context) { + results.insert(context); +} + //===----------------------------------------------------------------------===// // MulFOp //===----------------------------------------------------------------------===// @@ -1439,6 +1566,22 @@ return success(); } +OpFoldResult SignExtendIOp::fold(ArrayRef operands) { + assert(operands.size() == 1 && "unary operation takes one operand"); + + if (!operands[0]) + return {}; + + if (operands[0].isa()) { + auto lhs = operands[0].cast(); + + return IntegerAttr::get( + getType(), lhs.getValue().sext(getType().getIntOrFloatBitWidth())); + } + + return {}; +} + //===----------------------------------------------------------------------===// // SignedDivIOp //===----------------------------------------------------------------------===// @@ -1669,6 +1812,178 @@ [](APInt a, APInt b) { return a - b; }); } +/// Canonicalize a sub of a constant and (constant +/- something) to simply be +/// a single operation that merges the two constants. +struct SubConstantReorder : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + LogicalResult matchAndRewrite(SubIOp subOp, + PatternRewriter &rewriter) const override { + if (auto origConstOp = subOp.getOperand(0).getDefiningOp()) { + + if (auto midAddOp = subOp.getOperand(1).getDefiningOp()) { + // c1 - (c2 + something) == (c1 - c2) - something + for (int j = 0; j < 2; j++) { + if (auto midConstOp = + midAddOp.getOperand(j).getDefiningOp()) { + auto nextConstant = rewriter.create( + subOp.getLoc(), + rewriter.getIntegerAttr( + subOp.getType(), + origConstOp.getValue().cast().getValue() - + midConstOp.getValue().cast().getValue())); + rewriter.replaceOpWithNewOp(subOp, nextConstant, + midAddOp.getOperand(1 - j)); + return success(); + } + } + } + + if (auto midSubOp = subOp.getOperand(0).getDefiningOp()) { + if (auto midConstOp = + midSubOp.getOperand(0).getDefiningOp()) { + // (c2 - something) - c1 == (c2 - c1) - something + auto nextConstant = rewriter.create( + subOp.getLoc(), + rewriter.getIntegerAttr( + subOp.getType(), + midConstOp.getValue().cast().getValue() - + origConstOp.getValue().cast().getValue())); + rewriter.replaceOpWithNewOp(subOp, nextConstant, + midSubOp.getOperand(1)); + return success(); + } + if (auto midConstOp = + midSubOp.getOperand(1).getDefiningOp()) { + // (something - c2) - c1 == something - (c1 + c2) + auto nextConstant = rewriter.create( + subOp.getLoc(), + rewriter.getIntegerAttr( + subOp.getType(), + origConstOp.getValue().cast().getValue() + + midConstOp.getValue().cast().getValue())); + rewriter.replaceOpWithNewOp(subOp, midSubOp.getOperand(0), + nextConstant); + return success(); + } + } + + if (auto midSubOp = subOp.getOperand(1).getDefiningOp()) { + if (auto midConstOp = + midSubOp.getOperand(0).getDefiningOp()) { + // c1 - (c2 - something) == (c1 - c2) + something + auto nextConstant = rewriter.create( + subOp.getLoc(), + rewriter.getIntegerAttr( + subOp.getType(), + origConstOp.getValue().cast().getValue() - + midConstOp.getValue().cast().getValue())); + rewriter.replaceOpWithNewOp(subOp, nextConstant, + midSubOp.getOperand(1)); + return success(); + } + if (auto midConstOp = + midSubOp.getOperand(1).getDefiningOp()) { + // c1 - (something - c2) == (c1 + c2) - something + auto nextConstant = rewriter.create( + subOp.getLoc(), + rewriter.getIntegerAttr( + subOp.getType(), + origConstOp.getValue().cast().getValue() + + midConstOp.getValue().cast().getValue())); + rewriter.replaceOpWithNewOp(subOp, nextConstant, + midSubOp.getOperand(0)); + return success(); + } + } + } + if (auto origConstOp = subOp.getOperand(1).getDefiningOp()) { + + if (auto midAddOp = subOp.getOperand(0).getDefiningOp()) { + // (c2 + something) - c1 == (c2 - c1) + something + for (int j = 0; j < 2; j++) { + if (auto midConstOp = + midAddOp.getOperand(j).getDefiningOp()) { + auto nextConstant = rewriter.create( + subOp.getLoc(), + rewriter.getIntegerAttr( + subOp.getType(), + midConstOp.getValue().cast().getValue() - + origConstOp.getValue().cast().getValue())); + rewriter.replaceOpWithNewOp(subOp, nextConstant, + midAddOp.getOperand(1 - j)); + return success(); + } + } + } + + if (auto midSubOp = subOp.getOperand(0).getDefiningOp()) { + if (auto midConstOp = + midSubOp.getOperand(0).getDefiningOp()) { + // (c2 - something) - c1 == (c2 - c1) - something + auto nextConstant = rewriter.create( + subOp.getLoc(), + rewriter.getIntegerAttr( + subOp.getType(), + midConstOp.getValue().cast().getValue() - + origConstOp.getValue().cast().getValue())); + rewriter.replaceOpWithNewOp(subOp, nextConstant, + midSubOp.getOperand(1)); + return success(); + } + if (auto midConstOp = + midSubOp.getOperand(1).getDefiningOp()) { + // (something - c2) - c1 == something - (c2 + c1) + auto nextConstant = rewriter.create( + subOp.getLoc(), + rewriter.getIntegerAttr( + subOp.getType(), + origConstOp.getValue().cast().getValue() + + midConstOp.getValue().cast().getValue())); + rewriter.replaceOpWithNewOp(subOp, midSubOp.getOperand(0), + nextConstant); + return success(); + } + } + + if (auto midSubOp = subOp.getOperand(1).getDefiningOp()) { + if (auto midConstOp = + midSubOp.getOperand(0).getDefiningOp()) { + // c1 - (c2 - something) == (c1 - c2) + something + auto nextConstant = rewriter.create( + subOp.getLoc(), + rewriter.getIntegerAttr( + subOp.getType(), + origConstOp.getValue().cast().getValue() - + midConstOp.getValue().cast().getValue())); + rewriter.replaceOpWithNewOp(subOp, nextConstant, + midSubOp.getOperand(1)); + return success(); + } + if (auto midConstOp = + midSubOp.getOperand(1).getDefiningOp()) { + // c1 - (something - c2) == (c1 - c2) - something + auto nextConstant = rewriter.create( + subOp.getLoc(), + rewriter.getIntegerAttr( + subOp.getType(), + origConstOp.getValue().cast().getValue() - + midConstOp.getValue().cast().getValue())); + rewriter.replaceOpWithNewOp(subOp, nextConstant, + midSubOp.getOperand(0)); + return success(); + } + } + } + return failure(); + } +}; + +void SubIOp::getCanonicalizationPatterns(OwningRewritePatternList &results, + MLIRContext *context) { + results.insert(context); +} + //===----------------------------------------------------------------------===// // UIToFPOp //===----------------------------------------------------------------------===// @@ -2673,7 +2988,19 @@ matchPattern(getOperand(), m_Op())) return getOperand().getDefiningOp()->getOperand(0); - return nullptr; + assert(operands.size() == 1 && "unary operation takes one operand"); + + if (!operands[0]) + return {}; + + if (operands[0].isa()) { + auto lhs = operands[0].cast(); + + return IntegerAttr::get( + getType(), lhs.getValue().trunc(getType().getIntOrFloatBitWidth())); + } + + return {}; } //===----------------------------------------------------------------------===// @@ -2747,6 +3074,72 @@ [](APInt a, APInt b) { return a ^ b; }); } +struct NotICmp : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + LogicalResult matchAndRewrite(XOrOp op, + PatternRewriter &rewriter) const override { + auto c1 = op.rhs().getDefiningOp(); + if (!c1) + return failure(); + if (c1.getValue().cast().getValue() != 1) + return failure(); + auto prev = op.lhs().getDefiningOp(); + if (!prev) + return failure(); + switch (prev.predicate()) { + case mlir::CmpIPredicate::eq: + rewriter.replaceOpWithNewOp(op, mlir::CmpIPredicate::ne, + prev.lhs(), prev.rhs()); + return success(); + case mlir::CmpIPredicate::ne: + rewriter.replaceOpWithNewOp(op, mlir::CmpIPredicate::eq, + prev.lhs(), prev.rhs()); + return success(); + + case mlir::CmpIPredicate::slt: + rewriter.replaceOpWithNewOp(op, mlir::CmpIPredicate::sge, + prev.lhs(), prev.rhs()); + return success(); + case mlir::CmpIPredicate::sle: + rewriter.replaceOpWithNewOp(op, mlir::CmpIPredicate::sgt, + prev.lhs(), prev.rhs()); + return success(); + case mlir::CmpIPredicate::sgt: + rewriter.replaceOpWithNewOp(op, mlir::CmpIPredicate::sle, + prev.lhs(), prev.rhs()); + return success(); + case mlir::CmpIPredicate::sge: + rewriter.replaceOpWithNewOp(op, mlir::CmpIPredicate::slt, + prev.lhs(), prev.rhs()); + return success(); + + case mlir::CmpIPredicate::ult: + rewriter.replaceOpWithNewOp(op, mlir::CmpIPredicate::uge, + prev.lhs(), prev.rhs()); + return success(); + case mlir::CmpIPredicate::ule: + rewriter.replaceOpWithNewOp(op, mlir::CmpIPredicate::ugt, + prev.lhs(), prev.rhs()); + return success(); + case mlir::CmpIPredicate::ugt: + rewriter.replaceOpWithNewOp(op, mlir::CmpIPredicate::ule, + prev.lhs(), prev.rhs()); + return success(); + case mlir::CmpIPredicate::uge: + rewriter.replaceOpWithNewOp(op, mlir::CmpIPredicate::ult, + prev.lhs(), prev.rhs()); + return success(); + } + return failure(); + } +}; + +void XOrOp::getCanonicalizationPatterns(OwningRewritePatternList &results, + MLIRContext *context) { + results.insert(context); +} + //===----------------------------------------------------------------------===// // ZeroExtendIOp //===----------------------------------------------------------------------===// diff --git a/mlir/test/Conversion/StandardToLLVM/convert-to-llvmir.mlir b/mlir/test/Conversion/StandardToLLVM/convert-to-llvmir.mlir --- a/mlir/test/Conversion/StandardToLLVM/convert-to-llvmir.mlir +++ b/mlir/test/Conversion/StandardToLLVM/convert-to-llvmir.mlir @@ -698,15 +698,13 @@ // Check sign and zero extension and truncation of integers. // CHECK-LABEL: @integer_extension_and_truncation -func @integer_extension_and_truncation() { -// CHECK-NEXT: %0 = llvm.mlir.constant(-3 : i3) : i3 - %0 = constant 5 : i3 -// CHECK-NEXT: = llvm.sext %0 : i3 to i6 - %1 = sexti %0 : i3 to i6 -// CHECK-NEXT: = llvm.zext %0 : i3 to i6 - %2 = zexti %0 : i3 to i6 -// CHECK-NEXT: = llvm.trunc %0 : i3 to i2 - %3 = trunci %0 : i3 to i2 +func @integer_extension_and_truncation(%arg0 : i3) { +// CHECK-NEXT: = llvm.sext %arg0 : i3 to i6 + %0 = sexti %arg0 : i3 to i6 +// CHECK-NEXT: = llvm.zext %arg0 : i3 to i6 + %1 = zexti %arg0 : i3 to i6 +// CHECK-NEXT: = llvm.trunc %arg0 : i3 to i2 + %2 = trunci %arg0 : i3 to i2 return } diff --git a/mlir/test/Dialect/Standard/canonicalize.mlir b/mlir/test/Dialect/Standard/canonicalize.mlir --- a/mlir/test/Dialect/Standard/canonicalize.mlir +++ b/mlir/test/Dialect/Standard/canonicalize.mlir @@ -306,3 +306,175 @@ %1 = select %0, %arg0, %arg1 : i64 return %1 : i64 } + + +// ----- + +// CHECK-LABEL: @tripleAddAdd +// CHECK: %[[cres:.+]] = constant 59 : index +// CHECK: %[[add:.+]] = addi %arg0, %[[cres]] : index +// CHECK: return %[[add]] +func @tripleAddAdd(%arg0: index) -> index { + %c17 = constant 17 : index + %c42 = constant 42 : index + %add1 = addi %c17, %arg0 : index + %add2 = addi %c42, %add1 : index + return %add2 : index +} + +// CHECK-LABEL: @tripleAddSub0 +// CHECK: %[[cres:.+]] = constant 59 : index +// CHECK: %[[add:.+]] = subi %[[cres]], %arg0 : index +// CHECK: return %[[add]] +func @tripleAddSub0(%arg0: index) -> index { + %c17 = constant 17 : index + %c42 = constant 42 : index + %add1 = subi %c17, %arg0 : index + %add2 = addi %c42, %add1 : index + return %add2 : index +} + +// CHECK-LABEL: @tripleAddSub1 +// CHECK: %[[cres:.+]] = constant 25 : index +// CHECK: %[[add:.+]] = addi %arg0, %[[cres]] : index +// CHECK: return %[[add]] +func @tripleAddSub1(%arg0: index) -> index { + %c17 = constant 17 : index + %c42 = constant 42 : index + %add1 = subi %arg0, %c17 : index + %add2 = addi %c42, %add1 : index + return %add2 : index +} + +// CHECK-LABEL: @tripleSubAdd0 +// CHECK: %[[cres:.+]] = constant 25 : index +// CHECK: %[[add:.+]] = subi %[[cres]], %arg0 : index +// CHECK: return %[[add]] +func @tripleSubAdd0(%arg0: index) -> index { + %c17 = constant 17 : index + %c42 = constant 42 : index + %add1 = addi %c17, %arg0 : index + %add2 = subi %c42, %add1 : index + return %add2 : index +} + +// CHECK-LABEL: @tripleSubAdd1 +// CHECK: %[[cres:.+]] = constant -25 : index +// CHECK: %[[add:.+]] = addi %arg0, %[[cres]] : index +// CHECK: return %[[add]] +func @tripleSubAdd1(%arg0: index) -> index { + %c17 = constant 17 : index + %c42 = constant 42 : index + %add1 = addi %c17, %arg0 : index + %add2 = subi %add1, %c42 : index + return %add2 : index +} + +// CHECK-LABEL: @tripleSubSub0 +// CHECK: %[[cres:.+]] = constant 25 : index +// CHECK: %[[add:.+]] = addi %arg0, %[[cres]] : index +// CHECK: return %[[add]] +func @tripleSubSub0(%arg0: index) -> index { + %c17 = constant 17 : index + %c42 = constant 42 : index + %add1 = subi %c17, %arg0 : index + %add2 = subi %c42, %add1 : index + return %add2 : index +} + +// CHECK-LABEL: @tripleSubSub1 +// CHECK: %[[cres:.+]] = constant -25 : index +// CHECK: %[[add:.+]] = subi %[[cres]], %arg0 : index +// CHECK: return %[[add]] +func @tripleSubSub1(%arg0: index) -> index { + %c17 = constant 17 : index + %c42 = constant 42 : index + %add1 = subi %c17, %arg0 : index + %add2 = subi %add1, %c42 : index + return %add2 : index +} + +// CHECK-LABEL: @tripleSubSub2 +// CHECK: %[[cres:.+]] = constant 59 : index +// CHECK: %[[add:.+]] = subi %[[cres]], %arg0 : index +// CHECK: return %[[add]] +func @tripleSubSub2(%arg0: index) -> index { + %c17 = constant 17 : index + %c42 = constant 42 : index + %add1 = subi %arg0, %c17 : index + %add2 = subi %c42, %add1 : index + return %add2 : index +} + +// CHECK-LABEL: @tripleSubSub3 +// CHECK: %[[cres:.+]] = constant 59 : index +// CHECK: %[[add:.+]] = subi %arg0, %[[cres]] : index +// CHECK: return %[[add]] +func @tripleSubSub3(%arg0: index) -> index { + %c17 = constant 17 : index + %c42 = constant 42 : index + %add1 = subi %arg0, %c17 : index + %add2 = subi %add1, %c42 : index + return %add2 : index +} + +// ----- + +// CHECK-LABEL: @branchCondProp +// CHECK: %true = constant true +// CHECK: %false = constant false +// CHECK: cond_br %arg0, ^bb1, ^bb2 +// CHECK: ^bb1: // pred: ^bb0 +// CHECK: "test.consumer1"(%true) : (i1) -> () +// CHECK: br ^bb3 +// CHECK: ^bb2: // pred: ^bb0 +// CHECK: "test.consumer2"(%false) : (i1) -> () +// CHECK: br ^bb3 +// CHECK: ^bb3: // 2 preds: ^bb1, ^bb2 +// CHECK: return +func @branchCondProp(%arg0: i1) { + cond_br %arg0, ^trueB, ^falseB + +^trueB: + "test.consumer1"(%arg0) : (i1) -> () + br ^exit + +^falseB: + "test.consumer2"(%arg0) : (i1) -> () + br ^exit + +^exit: + return +} + +// ----- + +// CHECK-LABEL: @indexCastOfSignExtend +// CHECK: %[[res:.+]] = index_cast %arg0 : i8 to index +// CHECK: return %[[res]] +func @indexCastOfSignExtend(%arg0: i8) -> index { + %ext = sexti %arg0 : i8 to i16 + %idx = index_cast %ext : i16 to index + return %idx : index +} + +// CHECK-LABEL: @signExtendConstant +// CHECK: %[[cres:.+]] = constant -2 : i16 +// CHECK: return %[[cres]] +func @signExtendConstant(%arg0: i8) -> i16 { + %c-2 = constant -2 : i8 + %ext = sexti %c-2 : i8 to i16 + return %ext : i16 +} + +// ----- + +// CHECK-LABEL: @notCmp +// CHECK: %[[cres:.+]] = cmpi ne, %arg0, %arg1 : i8 +// CHECK: return %[[cres]] +func @notCmp(%arg0: i8, %arg1: i8) -> i1 { + %true = constant true + %cmp = cmpi "eq", %arg0, %arg1 : i8 + %ncmp = xor %cmp, %true : i1 + return %ncmp : i1 +}