Index: mlir/include/mlir/Dialect/Index/IR/IndexOps.td =================================================================== --- mlir/include/mlir/Dialect/Index/IR/IndexOps.td +++ mlir/include/mlir/Dialect/Index/IR/IndexOps.td @@ -343,6 +343,63 @@ }]; } +//===----------------------------------------------------------------------===// +// AndOp +//===----------------------------------------------------------------------===// + +def Index_AndOp : IndexBinaryOp<"and"> { + let summary = "index bitwise and"; + let description = [{ + The `index.and` operation takes two index values and computes their bitwise + and. + + Example: + + ```mlir + // c = a & b + %c = index.and %a, %b + ``` + }]; +} + +//===----------------------------------------------------------------------===// +// OrOp +//===----------------------------------------------------------------------===// + +def Index_OrOp : IndexBinaryOp<"or"> { + let summary = "index bitwise or"; + let description = [{ + The `index.or` operation takes two index values and computes their bitwise + or. + + Example: + + ```mlir + // c = a | b + %c = index.or %a, %b + ``` + }]; +} + +//===----------------------------------------------------------------------===// +// XorOp +//===----------------------------------------------------------------------===// + +def Index_XOrOp : IndexBinaryOp<"xor"> { + let summary = "index bitwise xor"; + let description = [{ + The `index.xor` operation takes two index values and computes their bitwise + xor. + + Example: + + ```mlir + // c = a ^ b + %c = index.xor %a, %b + ``` + }]; +} + //===----------------------------------------------------------------------===// // CastSOp //===----------------------------------------------------------------------===// Index: mlir/lib/Conversion/IndexToLLVM/IndexToLLVM.cpp =================================================================== --- mlir/lib/Conversion/IndexToLLVM/IndexToLLVM.cpp +++ mlir/lib/Conversion/IndexToLLVM/IndexToLLVM.cpp @@ -273,6 +273,9 @@ mlir::OneToOneConvertToLLVMPattern; using ConvertIndexShrU = mlir::OneToOneConvertToLLVMPattern; +using ConvertIndexAnd = mlir::OneToOneConvertToLLVMPattern; +using ConvertIndexOr = mlir::OneToOneConvertToLLVMPattern; +using ConvertIndexXor = mlir::OneToOneConvertToLLVMPattern; using ConvertIndexBoolConstant = mlir::OneToOneConvertToLLVMPattern; @@ -298,6 +301,9 @@ ConvertIndexShl, ConvertIndexShrS, ConvertIndexShrU, + ConvertIndexAnd, + ConvertIndexOr, + ConvertIndexXor, ConvertIndexCeilDivS, ConvertIndexCeilDivU, ConvertIndexFloorDivS, Index: mlir/lib/Dialect/Index/IR/IndexOps.cpp =================================================================== --- mlir/lib/Dialect/Index/IR/IndexOps.cpp +++ mlir/lib/Dialect/Index/IR/IndexOps.cpp @@ -329,6 +329,33 @@ }); } +//===----------------------------------------------------------------------===// +// AndOp +//===----------------------------------------------------------------------===// + +OpFoldResult AndOp::fold(ArrayRef operands) { + return foldBinaryOpUnchecked( + operands, [](const APInt &lhs, const APInt &rhs) { return lhs & rhs; }); +} + +//===----------------------------------------------------------------------===// +// OrOp +//===----------------------------------------------------------------------===// + +OpFoldResult OrOp::fold(ArrayRef operands) { + return foldBinaryOpUnchecked( + operands, [](const APInt &lhs, const APInt &rhs) { return lhs | rhs; }); +} + +//===----------------------------------------------------------------------===// +// XOrOp +//===----------------------------------------------------------------------===// + +OpFoldResult XOrOp::fold(ArrayRef operands) { + return foldBinaryOpUnchecked( + operands, [](const APInt &lhs, const APInt &rhs) { return lhs ^ rhs; }); +} + //===----------------------------------------------------------------------===// // CastSOp //===----------------------------------------------------------------------===// Index: mlir/test/Conversion/IndexToLLVM/index-to-llvm.mlir =================================================================== --- mlir/test/Conversion/IndexToLLVM/index-to-llvm.mlir +++ mlir/test/Conversion/IndexToLLVM/index-to-llvm.mlir @@ -28,8 +28,14 @@ %10 = index.shrs %a, %b // CHECK: llvm.lshr %11 = index.shru %a, %b + // CHECK: llvm.add + %12 = index.add %a, %b + // CHECK: llvm.or + %13 = index.or %a, %b + // CHECK: llvm.xor + %14 = index.xor %a, %b // CHECK: llvm.mlir.constant(true - %12 = index.bool.constant true + %15 = index.bool.constant true return } Index: mlir/test/Dialect/Index/index-canonicalize.mlir =================================================================== --- mlir/test/Dialect/Index/index-canonicalize.mlir +++ mlir/test/Dialect/Index/index-canonicalize.mlir @@ -384,6 +384,36 @@ return %0 : index } +// CHECK-LABEL: @and +func.func @and() -> index { + %lhs = index.constant 5 + %rhs = index.constant 1 + // CHECK: %[[A:.*]] = index.constant 1 + %0 = index.and %lhs, %rhs + // CHECK: return %[[A]] + return %0 : index +} + +// CHECK-LABEL: @or +func.func @or() -> index { + %lhs = index.constant 5 + %rhs = index.constant 2 + // CHECK: %[[A:.*]] = index.constant 7 + %0 = index.or %lhs, %rhs + // CHECK: return %[[A]] + return %0 : index +} + +// CHECK-LABEL: @xor +func.func @xor() -> index { + %lhs = index.constant 5 + %rhs = index.constant 1 + // CHECK: %[[A:.*]] = index.constant 4 + %0 = index.xor %lhs, %rhs + // CHECK: return %[[A]] + return %0 : index +} + // CHECK-LABEL: @cmp func.func @cmp() -> (i1, i1, i1, i1) { %a = index.constant 0 Index: mlir/test/Dialect/Index/index-ops.mlir =================================================================== --- mlir/test/Dialect/Index/index-ops.mlir +++ mlir/test/Dialect/Index/index-ops.mlir @@ -33,6 +33,12 @@ %13 = index.shrs %a, %b // CHECK-NEXT: index.shru %[[A]], %[[B]] %14 = index.shru %a, %b + // CHECK-NEXT: index.and %[[A]], %[[B]] + %15 = index.and %a, %b + // CHECK-NEXT: index.or %[[A]], %[[B]] + %16 = index.or %a, %b + // CHECK-NEXT: index.xor %[[A]], %[[B]] + %17 = index.xor %a, %b return }