https://github.com/cenewcombe updated https://github.com/llvm/llvm-project/pull/191874
>From 68952c5acbab81143d09101ea66276ff9bf9f189 Mon Sep 17 00:00:00 2001
From: Caroline Newcombe <caroline.newcombe at hpe.com>
Date: Mon, 30 Mar 2026 08:56:45 -0500
Subject: [PATCH 1/2] [flang] Implement lowering for BOZ literal arguments in
BGE, BLE, BGT, BLT
---
flang/lib/Lower/ConvertExprToHLFIR.cpp | 14 ++++++++-
flang/test/Lower/Intrinsics/bge.f90 | 42 ++++++++++++++++++++++++++
flang/test/Lower/Intrinsics/bgt.f90 | 28 +++++++++++++++++
flang/test/Lower/Intrinsics/ble.f90 | 28 +++++++++++++++++
flang/test/Lower/Intrinsics/blt.f90 | 28 +++++++++++++++++
5 files changed, 139 insertions(+), 1 deletion(-)
diff --git a/flang/lib/Lower/ConvertExprToHLFIR.cpp b/flang/lib/Lower/ConvertExprToHLFIR.cpp
index 5ee409b031357..dc787dfdf8a7b 100644
--- a/flang/lib/Lower/ConvertExprToHLFIR.cpp
+++ b/flang/lib/Lower/ConvertExprToHLFIR.cpp
@@ -1620,7 +1620,19 @@ class HlfirBuilder {
private:
hlfir::EntityWithAttributes
gen(const Fortran::evaluate::BOZLiteralConstant &expr) {
- TODO(getLoc(), "BOZ");
+ // BOZ literals reach lowering only from BGE/BGT/BLE/BLT intrinsics when at
+ // least one operand is not constant (otherwise folds). For all other
+ // intrinsics, semantics converts BOZ to the expected type before lowering.
+ Fortran::evaluate::Constant<Fortran::evaluate::LargestInt> intConstant{
+ expr};
+ mlir::Location loc{getLoc()};
+ fir::ExtendedValue exv{Fortran::lower::convertConstant(
+ getConverter(), loc, intConstant,
+ /*outlineBigConstantInReadOnlyMemory=*/false)};
+ if (const auto *scalarBox{exv.getUnboxed()})
+ if (fir::isa_trivial(scalarBox->getType()))
+ return hlfir::EntityWithAttributes(*scalarBox);
+ fir::emitFatalError(loc, "BOZ literal was lowered to unexpected format");
}
hlfir::EntityWithAttributes gen(const Fortran::evaluate::NullPointer &expr) {
diff --git a/flang/test/Lower/Intrinsics/bge.f90 b/flang/test/Lower/Intrinsics/bge.f90
index f4d05e38f6991..5daab71322525 100644
--- a/flang/test/Lower/Intrinsics/bge.f90
+++ b/flang/test/Lower/Intrinsics/bge.f90
@@ -197,3 +197,45 @@ subroutine bge_test11(c)
! CHECK: %[[V:.*]] = fir.convert %[[R]] : (i1) -> !fir.logical<4>
! CHECK: hlfir.assign %[[V]] to %[[C_DECL]]#0 : !fir.logical<4>, !fir.ref<!fir.logical<4>>
end subroutine bge_test11
+
+! Test BOZ literal as second argument
+! CHECK-LABEL: func.func @_QPbge_boz_second(
+subroutine bge_boz_second(a, c)
+ integer :: a
+ logical :: c
+ c = bge(a, z'FF')
+ ! CHECK: %[[BOZ:.*]] = arith.constant 255 : i128
+ ! CHECK: %[[A:.*]] = fir.load %{{.*}} : !fir.ref<i32>
+ ! CHECK: %[[EXT:.*]] = arith.extui %[[A]] : i32 to i128
+ ! CHECK: %[[CMP:.*]] = arith.cmpi uge, %[[EXT]], %[[BOZ]] : i128
+ ! CHECK: %[[RES:.*]] = fir.convert %[[CMP]] : (i1) -> !fir.logical<4>
+ ! CHECK: hlfir.assign %[[RES]] to %{{.*}}
+end subroutine bge_boz_second
+
+! Test BOZ literal as first argument
+! CHECK-LABEL: func.func @_QPbge_boz_first(
+subroutine bge_boz_first(a, c)
+ integer :: a
+ logical :: c
+ c = bge(z'FF', a)
+ ! CHECK: %[[BOZ:.*]] = arith.constant 255 : i128
+ ! CHECK: %[[A:.*]] = fir.load %{{.*}} : !fir.ref<i32>
+ ! CHECK: %[[EXT:.*]] = arith.extui %[[A]] : i32 to i128
+ ! CHECK: %[[CMP:.*]] = arith.cmpi uge, %[[BOZ]], %[[EXT]] : i128
+ ! CHECK: %[[RES:.*]] = fir.convert %[[CMP]] : (i1) -> !fir.logical<4>
+ ! CHECK: hlfir.assign %[[RES]] to %{{.*}}
+end subroutine bge_boz_first
+
+! Test BOZ literal wider than companion integer type
+! CHECK-LABEL: func.func @_QPbge_boz_wide(
+subroutine bge_boz_wide(a, c)
+ integer :: a
+ logical :: c
+ c = bge(a, z'1FFFFFFFF')
+ ! CHECK: %[[BOZ:.*]] = arith.constant 8589934591 : i128
+ ! CHECK: %[[A:.*]] = fir.load %{{.*}} : !fir.ref<i32>
+ ! CHECK: %[[EXT:.*]] = arith.extui %[[A]] : i32 to i128
+ ! CHECK: %[[CMP:.*]] = arith.cmpi uge, %[[EXT]], %[[BOZ]] : i128
+ ! CHECK: %[[RES:.*]] = fir.convert %[[CMP]] : (i1) -> !fir.logical<4>
+ ! CHECK: hlfir.assign %[[RES]] to %{{.*}}
+end subroutine bge_boz_wide
diff --git a/flang/test/Lower/Intrinsics/bgt.f90 b/flang/test/Lower/Intrinsics/bgt.f90
index 95a4a875de03e..068b73956028b 100644
--- a/flang/test/Lower/Intrinsics/bgt.f90
+++ b/flang/test/Lower/Intrinsics/bgt.f90
@@ -197,3 +197,31 @@ subroutine bgt_test11(c)
! CHECK: %[[V:.*]] = fir.convert %[[R]] : (i1) -> !fir.logical<4>
! CHECK: hlfir.assign %[[V]] to %[[C_DECL]]#0 : !fir.logical<4>, !fir.ref<!fir.logical<4>>
end subroutine bgt_test11
+
+! Test BOZ literal as second argument
+! CHECK-LABEL: func.func @_QPbgt_boz_second(
+subroutine bgt_boz_second(a, c)
+ integer :: a
+ logical :: c
+ c = bgt(a, z'FF')
+ ! CHECK: %[[BOZ:.*]] = arith.constant 255 : i128
+ ! CHECK: %[[A:.*]] = fir.load %{{.*}} : !fir.ref<i32>
+ ! CHECK: %[[EXT:.*]] = arith.extui %[[A]] : i32 to i128
+ ! CHECK: %[[CMP:.*]] = arith.cmpi ugt, %[[EXT]], %[[BOZ]] : i128
+ ! CHECK: %[[RES:.*]] = fir.convert %[[CMP]] : (i1) -> !fir.logical<4>
+ ! CHECK: hlfir.assign %[[RES]] to %{{.*}}
+end subroutine bgt_boz_second
+
+! Test BOZ literal as first argument
+! CHECK-LABEL: func.func @_QPbgt_boz_first(
+subroutine bgt_boz_first(a, c)
+ integer :: a
+ logical :: c
+ c = bgt(z'FF', a)
+ ! CHECK: %[[BOZ:.*]] = arith.constant 255 : i128
+ ! CHECK: %[[A:.*]] = fir.load %{{.*}} : !fir.ref<i32>
+ ! CHECK: %[[EXT:.*]] = arith.extui %[[A]] : i32 to i128
+ ! CHECK: %[[CMP:.*]] = arith.cmpi ugt, %[[BOZ]], %[[EXT]] : i128
+ ! CHECK: %[[RES:.*]] = fir.convert %[[CMP]] : (i1) -> !fir.logical<4>
+ ! CHECK: hlfir.assign %[[RES]] to %{{.*}}
+end subroutine bgt_boz_first
diff --git a/flang/test/Lower/Intrinsics/ble.f90 b/flang/test/Lower/Intrinsics/ble.f90
index 4605227710358..f54aa56b30805 100644
--- a/flang/test/Lower/Intrinsics/ble.f90
+++ b/flang/test/Lower/Intrinsics/ble.f90
@@ -197,3 +197,31 @@ subroutine ble_test11(c)
! CHECK: %[[V:.*]] = fir.convert %[[R]] : (i1) -> !fir.logical<4>
! CHECK: hlfir.assign %[[V]] to %[[C_DECL]]#0 : !fir.logical<4>, !fir.ref<!fir.logical<4>>
end subroutine ble_test11
+
+! Test BOZ literal as second argument
+! CHECK-LABEL: func.func @_QPble_boz_second(
+subroutine ble_boz_second(a, c)
+ integer :: a
+ logical :: c
+ c = ble(a, z'FF')
+ ! CHECK: %[[BOZ:.*]] = arith.constant 255 : i128
+ ! CHECK: %[[A:.*]] = fir.load %{{.*}} : !fir.ref<i32>
+ ! CHECK: %[[EXT:.*]] = arith.extui %[[A]] : i32 to i128
+ ! CHECK: %[[CMP:.*]] = arith.cmpi ule, %[[EXT]], %[[BOZ]] : i128
+ ! CHECK: %[[RES:.*]] = fir.convert %[[CMP]] : (i1) -> !fir.logical<4>
+ ! CHECK: hlfir.assign %[[RES]] to %{{.*}}
+end subroutine ble_boz_second
+
+! Test BOZ literal as first argument
+! CHECK-LABEL: func.func @_QPble_boz_first(
+subroutine ble_boz_first(a, c)
+ integer :: a
+ logical :: c
+ c = ble(z'FF', a)
+ ! CHECK: %[[BOZ:.*]] = arith.constant 255 : i128
+ ! CHECK: %[[A:.*]] = fir.load %{{.*}} : !fir.ref<i32>
+ ! CHECK: %[[EXT:.*]] = arith.extui %[[A]] : i32 to i128
+ ! CHECK: %[[CMP:.*]] = arith.cmpi ule, %[[BOZ]], %[[EXT]] : i128
+ ! CHECK: %[[RES:.*]] = fir.convert %[[CMP]] : (i1) -> !fir.logical<4>
+ ! CHECK: hlfir.assign %[[RES]] to %{{.*}}
+end subroutine ble_boz_first
diff --git a/flang/test/Lower/Intrinsics/blt.f90 b/flang/test/Lower/Intrinsics/blt.f90
index 89e743c64a081..b7e14800a62c0 100644
--- a/flang/test/Lower/Intrinsics/blt.f90
+++ b/flang/test/Lower/Intrinsics/blt.f90
@@ -197,3 +197,31 @@ subroutine blt_test11(c)
! CHECK: %[[V:.*]] = fir.convert %[[R]] : (i1) -> !fir.logical<4>
! CHECK: hlfir.assign %[[V]] to %[[C_DECL]]#0 : !fir.logical<4>, !fir.ref<!fir.logical<4>>
end subroutine blt_test11
+
+! Test BOZ literal as second argument
+! CHECK-LABEL: func.func @_QPblt_boz_second(
+subroutine blt_boz_second(a, c)
+ integer :: a
+ logical :: c
+ c = blt(a, z'FF')
+ ! CHECK: %[[BOZ:.*]] = arith.constant 255 : i128
+ ! CHECK: %[[A:.*]] = fir.load %{{.*}} : !fir.ref<i32>
+ ! CHECK: %[[EXT:.*]] = arith.extui %[[A]] : i32 to i128
+ ! CHECK: %[[CMP:.*]] = arith.cmpi ult, %[[EXT]], %[[BOZ]] : i128
+ ! CHECK: %[[RES:.*]] = fir.convert %[[CMP]] : (i1) -> !fir.logical<4>
+ ! CHECK: hlfir.assign %[[RES]] to %{{.*}}
+end subroutine blt_boz_second
+
+! Test BOZ literal as first argument
+! CHECK-LABEL: func.func @_QPblt_boz_first(
+subroutine blt_boz_first(a, c)
+ integer :: a
+ logical :: c
+ c = blt(z'FF', a)
+ ! CHECK: %[[BOZ:.*]] = arith.constant 255 : i128
+ ! CHECK: %[[A:.*]] = fir.load %{{.*}} : !fir.ref<i32>
+ ! CHECK: %[[EXT:.*]] = arith.extui %[[A]] : i32 to i128
+ ! CHECK: %[[CMP:.*]] = arith.cmpi ult, %[[BOZ]], %[[EXT]] : i128
+ ! CHECK: %[[RES:.*]] = fir.convert %[[CMP]] : (i1) -> !fir.logical<4>
+ ! CHECK: hlfir.assign %[[RES]] to %{{.*}}
+end subroutine blt_boz_first
>From 26668028e2ce6d8b11b2f95971242a3953bd0a6b Mon Sep 17 00:00:00 2001
From: Caroline Newcombe <caroline.newcombe at hpe.com>
Date: Thu, 23 Apr 2026 10:53:42 -0500
Subject: [PATCH 2/2] [flang] Additional tests for BOZ arguments in BGE, BLE,
BGT, BLT
---
flang/test/Lower/Intrinsics/bge.f90 | 10 ++++++++++
flang/test/Lower/Intrinsics/bgt.f90 | 10 ++++++++++
flang/test/Lower/Intrinsics/ble.f90 | 10 ++++++++++
flang/test/Lower/Intrinsics/blt.f90 | 10 ++++++++++
4 files changed, 40 insertions(+)
diff --git a/flang/test/Lower/Intrinsics/bge.f90 b/flang/test/Lower/Intrinsics/bge.f90
index 5daab71322525..d65797bac5ad7 100644
--- a/flang/test/Lower/Intrinsics/bge.f90
+++ b/flang/test/Lower/Intrinsics/bge.f90
@@ -239,3 +239,13 @@ subroutine bge_boz_wide(a, c)
! CHECK: %[[RES:.*]] = fir.convert %[[CMP]] : (i1) -> !fir.logical<4>
! CHECK: hlfir.assign %[[RES]] to %{{.*}}
end subroutine bge_boz_wide
+
+! Test BOZ literal for both arguments (folded at compile time)
+! CHECK-LABEL: func.func @_QPbge_boz_both(
+subroutine bge_boz_both(c)
+ logical :: c
+ c = bge(z'FF', z'FE')
+ ! CHECK: %[[R:.*]] = arith.constant true
+ ! CHECK: %[[V:.*]] = fir.convert %[[R]] : (i1) -> !fir.logical<4>
+ ! CHECK: hlfir.assign %[[V]] to %{{.*}}
+end subroutine bge_boz_both
diff --git a/flang/test/Lower/Intrinsics/bgt.f90 b/flang/test/Lower/Intrinsics/bgt.f90
index 068b73956028b..77d6a6115417f 100644
--- a/flang/test/Lower/Intrinsics/bgt.f90
+++ b/flang/test/Lower/Intrinsics/bgt.f90
@@ -225,3 +225,13 @@ subroutine bgt_boz_first(a, c)
! CHECK: %[[RES:.*]] = fir.convert %[[CMP]] : (i1) -> !fir.logical<4>
! CHECK: hlfir.assign %[[RES]] to %{{.*}}
end subroutine bgt_boz_first
+
+! Test BOZ literal for both arguments (folded at compile time)
+! CHECK-LABEL: func.func @_QPbgt_boz_both(
+subroutine bgt_boz_both(c)
+ logical :: c
+ c = bgt(z'FF', z'FE')
+ ! CHECK: %[[R:.*]] = arith.constant true
+ ! CHECK: %[[V:.*]] = fir.convert %[[R]] : (i1) -> !fir.logical<4>
+ ! CHECK: hlfir.assign %[[V]] to %{{.*}}
+end subroutine bgt_boz_both
diff --git a/flang/test/Lower/Intrinsics/ble.f90 b/flang/test/Lower/Intrinsics/ble.f90
index f54aa56b30805..da325d361e871 100644
--- a/flang/test/Lower/Intrinsics/ble.f90
+++ b/flang/test/Lower/Intrinsics/ble.f90
@@ -225,3 +225,13 @@ subroutine ble_boz_first(a, c)
! CHECK: %[[RES:.*]] = fir.convert %[[CMP]] : (i1) -> !fir.logical<4>
! CHECK: hlfir.assign %[[RES]] to %{{.*}}
end subroutine ble_boz_first
+
+! Test BOZ literal for both arguments (folded at compile time)
+! CHECK-LABEL: func.func @_QPble_boz_both(
+subroutine ble_boz_both(c)
+ logical :: c
+ c = ble(z'FF', z'FE')
+ ! CHECK: %[[R:.*]] = arith.constant false
+ ! CHECK: %[[V:.*]] = fir.convert %[[R]] : (i1) -> !fir.logical<4>
+ ! CHECK: hlfir.assign %[[V]] to %{{.*}}
+end subroutine ble_boz_both
diff --git a/flang/test/Lower/Intrinsics/blt.f90 b/flang/test/Lower/Intrinsics/blt.f90
index b7e14800a62c0..c9d527fb5e396 100644
--- a/flang/test/Lower/Intrinsics/blt.f90
+++ b/flang/test/Lower/Intrinsics/blt.f90
@@ -225,3 +225,13 @@ subroutine blt_boz_first(a, c)
! CHECK: %[[RES:.*]] = fir.convert %[[CMP]] : (i1) -> !fir.logical<4>
! CHECK: hlfir.assign %[[RES]] to %{{.*}}
end subroutine blt_boz_first
+
+! Test BOZ literal for both arguments (folded at compile time)
+! CHECK-LABEL: func.func @_QPblt_boz_both(
+subroutine blt_boz_both(c)
+ logical :: c
+ c = blt(z'FF', z'FE')
+ ! CHECK: %[[R:.*]] = arith.constant false
+ ! CHECK: %[[V:.*]] = fir.convert %[[R]] : (i1) -> !fir.logical<4>
+ ! CHECK: hlfir.assign %[[V]] to %{{.*}}
+end subroutine blt_boz_both