}];
let hasFolder = 1;
+ let hasCanonicalizer = 1;
}
//===----------------------------------------------------------------------===//
let printer = [{
return printStandardCastOp(this->getOperation(), p);
}];
+ let hasFolder = 1;
}
//===----------------------------------------------------------------------===//
return {};
}
+namespace {
+/// index_cast(sign_extend x) => index_cast(x)
+struct IndexCastOfSExt : public OpRewritePattern<IndexCastOp> {
+ using OpRewritePattern<IndexCastOp>::OpRewritePattern;
+
+ LogicalResult matchAndRewrite(IndexCastOp op,
+ PatternRewriter &rewriter) const override {
+
+ if (auto extop = op.getOperand().getDefiningOp<SignExtendIOp>()) {
+ op.setOperand(extop.getOperand());
+ return success();
+ }
+ return failure();
+ }
+};
+
+} // namespace
+
+void IndexCastOp::getCanonicalizationPatterns(OwningRewritePatternList &results,
+ MLIRContext *context) {
+ results.insert<IndexCastOfSExt>(context);
+}
+
//===----------------------------------------------------------------------===//
// MulFOp
//===----------------------------------------------------------------------===//
return success();
}
+OpFoldResult SignExtendIOp::fold(ArrayRef<Attribute> operands) {
+ assert(operands.size() == 1 && "unary operation takes one operand");
+
+ if (!operands[0])
+ return {};
+
+ if (auto lhs = operands[0].dyn_cast<IntegerAttr>()) {
+ return IntegerAttr::get(
+ getType(), lhs.getValue().sext(getType().getIntOrFloatBitWidth()));
+ }
+
+ return {};
+}
+
//===----------------------------------------------------------------------===//
// SignedDivIOp
//===----------------------------------------------------------------------===//
matchPattern(getOperand(), m_Op<SignExtendIOp>()))
return getOperand().getDefiningOp()->getOperand(0);
- return nullptr;
+ assert(operands.size() == 1 && "unary operation takes one operand");
+
+ if (!operands[0])
+ return {};
+
+ if (auto lhs = operands[0].dyn_cast<IntegerAttr>()) {
+
+ return IntegerAttr::get(
+ getType(), lhs.getValue().trunc(getType().getIntOrFloatBitWidth()));
+ }
+
+ return {};
}
//===----------------------------------------------------------------------===//
// 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
}
%1 = select %0, %arg0, %arg1 : i64
return %1 : i64
}
+
+// -----
+
+// 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() -> i16 {
+ %c-2 = constant -2 : i8
+ %ext = sexti %c-2 : i8 to i16
+ return %ext : i16
+}
+
+// CHECK-LABEL: @truncConstant
+// CHECK: %[[cres:.+]] = constant -2 : i16
+// CHECK: return %[[cres]]
+func @truncConstant(%arg0: i8) -> i16 {
+ %c-2 = constant -2 : i32
+ %tr = trunci %c-2 : i32 to i16
+ return %tr : i16
+}