[flang-commits] [flang] [flang] Add definition of hlfir.cmpchar operation. (PR #155457)
via flang-commits
flang-commits at lists.llvm.org
Tue Aug 26 10:54:04 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-fir-hlfir
Author: Valery Dmitriev (valerydmit)
<details>
<summary>Changes</summary>
Fortran character comparison now lowered early into a runtime call. It is going to be lowered into the operation, so that later it could be optimized as inline code or end up into a runtime call.
---
Full diff: https://github.com/llvm/llvm-project/pull/155457.diff
3 Files Affected:
- (modified) flang/include/flang/Optimizer/HLFIR/HLFIROps.td (+20)
- (modified) flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp (+34)
- (modified) flang/test/HLFIR/invalid.fir (+11)
``````````diff
diff --git a/flang/include/flang/Optimizer/HLFIR/HLFIROps.td b/flang/include/flang/Optimizer/HLFIR/HLFIROps.td
index db3fb0b90464d..f58dde589aaf5 100644
--- a/flang/include/flang/Optimizer/HLFIR/HLFIROps.td
+++ b/flang/include/flang/Optimizer/HLFIR/HLFIROps.td
@@ -348,6 +348,26 @@ def hlfir_ConcatOp : hlfir_Op<"concat",
let hasVerifier = 1;
}
+def hlfir_CmpCharOp : hlfir_Op<"cmpchar",
+ [DeclareOpInterfaceMethods<MemoryEffectsOpInterface>]> {
+ let summary = "compare two characters";
+ let description = [{
+ Compare two character strings of a same character kind.
+ }];
+
+ let arguments = (ins Arith_CmpIPredicateAttr:$predicate,
+ AnyScalarCharacterEntity:$lchr,
+ AnyScalarCharacterEntity:$rchr);
+
+ let results = (outs I1);
+
+ let assemblyFormat = [{
+ $predicate $lchr $rchr attr-dict `:` functional-type(operands, results)
+ }];
+
+ let hasVerifier = 1;
+}
+
def hlfir_AllOp : hlfir_Op<"all", [DeclareOpInterfaceMethods<MemoryEffectsOpInterface>]> {
let summary = "ALL transformational intrinsic";
let description = [{
diff --git a/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp b/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp
index 3c5095da0145a..964d183631186 100644
--- a/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp
+++ b/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp
@@ -820,6 +820,40 @@ void hlfir::ConcatOp::getEffects(
getIntrinsicEffects(getOperation(), effects);
}
+//===----------------------------------------------------------------------===//
+// CmpCharOp
+//===----------------------------------------------------------------------===//
+
+llvm::LogicalResult hlfir::CmpCharOp::verify() {
+ mlir::Value lchr = getLchr();
+ mlir::Value rchr = getRchr();
+
+ unsigned kind = getCharacterKind(lchr.getType());
+ if (kind != getCharacterKind(rchr.getType()))
+ return emitOpError("character arguments must have the same KIND");
+
+ switch (getPredicate()) {
+ case mlir::arith::CmpIPredicate::slt:
+ case mlir::arith::CmpIPredicate::sle:
+ case mlir::arith::CmpIPredicate::eq:
+ case mlir::arith::CmpIPredicate::ne:
+ case mlir::arith::CmpIPredicate::sgt:
+ case mlir::arith::CmpIPredicate::sge:
+ break;
+ default:
+ return emitOpError("expected signed predicate");
+ }
+
+ return mlir::success();
+}
+
+void hlfir::CmpCharOp::getEffects(
+ llvm::SmallVectorImpl<
+ mlir::SideEffects::EffectInstance<mlir::MemoryEffects::Effect>>
+ &effects) {
+ getIntrinsicEffects(getOperation(), effects);
+}
+
//===----------------------------------------------------------------------===//
// NumericalReductionOp
//===----------------------------------------------------------------------===//
diff --git a/flang/test/HLFIR/invalid.fir b/flang/test/HLFIR/invalid.fir
index 0f54a0250294b..b4baedb1e6477 100644
--- a/flang/test/HLFIR/invalid.fir
+++ b/flang/test/HLFIR/invalid.fir
@@ -296,6 +296,17 @@ func.func @bad_concat_4(%arg0: !fir.ref<!fir.char<1,30>>) {
return
}
+// -----
+func.func @bad_cmpchar_1(%arg0: !fir.ref<!fir.char<1,10>>, %arg1: !fir.ref<!fir.char<2,10>>) {
+ // expected-error at +1 {{'hlfir.cmpchar' op character arguments must have the same KIND}}
+ %0 = hlfir.cmpchar ne %arg0 %arg1 : (!fir.ref<!fir.char<1,10>>, !fir.ref<!fir.char<2,10>>) -> i1
+}
+
+func.func @bad_cmpchar_2(%arg0: !fir.ref<!fir.char<1,10>>, %arg1: !fir.ref<!fir.char<1,10>>) {
+ // expected-error at +1 {{'hlfir.cmpchar' op expected signed predicate}}
+ %0 = hlfir.cmpchar ugt %arg0 %arg1 : (!fir.ref<!fir.char<1,10>>, !fir.ref<!fir.char<1,10>>) -> i1
+}
+
// -----
func.func @bad_any1(%arg0: !hlfir.expr<?x!fir.logical<4>>) {
// expected-error at +1 {{'hlfir.any' op result must have the same element type as MASK argument}}
``````````
</details>
https://github.com/llvm/llvm-project/pull/155457
More information about the flang-commits
mailing list