[flang-commits] [flang] b8c6f41 - [flang][OpenMP] Do not set nuw on canonical loop trip count span (#229776)
via flang-commits
flang-commits at lists.llvm.org
Thu Oct 8 02:57:30 PDT 2026
Author: jeanPerier
Date: 2026-10-08T11:57:24+02:00
New Revision: b8c6f411414dbdf03b2cb2ab643da34b6c66398c
URL: https://github.com/llvm/llvm-project/commit/b8c6f411414dbdf03b2cb2ab643da34b6c66398c
DIFF: https://github.com/llvm/llvm-project/commit/b8c6f411414dbdf03b2cb2ab643da34b6c66398c.diff
LOG: [flang][OpenMP] Do not set nuw on canonical loop trip count span (#229776)
lb <= ub is a signed comparison and does not imply that ub - lb does not
wrap as unsigned (e.g. when lb is negative and ub is not), so the nuw
flag on the span computation could produce poison.
Fixes https://github.com/llvm/llvm-project/issues/229739
Added:
Modified:
flang/lib/Lower/OpenMP/OpenMP.cpp
flang/test/Lower/OpenMP/canonical-loop-trip-count.f90
flang/test/Lower/OpenMP/fuse01.f90
flang/test/Lower/OpenMP/fuse02.f90
flang/test/Lower/OpenMP/tile01.f90
flang/test/Lower/OpenMP/tile02.f90
flang/test/Lower/OpenMP/unroll-heuristic01.f90
flang/test/Lower/OpenMP/unroll-heuristic02.f90
flang/test/Lower/OpenMP/unroll-heuristic03.f90
flang/test/Lower/OpenMP/unroll-partial01.f90
Removed:
################################################################################
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 0b20eb1c16dc1..bdc6bb0073cff 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -3091,9 +3091,12 @@ static void genCanonicalLoopNest(
loc, isDownwards, loopLBVar, loopUBVar);
// Compute the trip count assuming lb <= ub. This guarantees that the result
- // is non-negative and we can use unsigned arithmetic.
- mlir::Value span = firOpBuilder.createOrFold<mlir::arith::SubIOp>(
- loc, ub, lb, ::mlir::arith::IntegerOverflowFlags::nuw);
+ // is non-negative and we can use unsigned arithmetic. The subtraction
+ // cannot be nuw: lb <= ub is a signed comparison, and lb may be negative
+ // while ub is not. It cannot be nsw either, since the span may not fit in
+ // the signed loop variable type.
+ mlir::Value span =
+ firOpBuilder.createOrFold<mlir::arith::SubIOp>(loc, ub, lb);
mlir::Value tcMinusOne =
firOpBuilder.createOrFold<mlir::arith::DivUIOp>(loc, span, incr);
mlir::Value tcIfLooping = firOpBuilder.createOrFold<mlir::arith::AddIOp>(
diff --git a/flang/test/Lower/OpenMP/canonical-loop-trip-count.f90 b/flang/test/Lower/OpenMP/canonical-loop-trip-count.f90
index e82f1acde2e73..e90aedcb98461 100644
--- a/flang/test/Lower/OpenMP/canonical-loop-trip-count.f90
+++ b/flang/test/Lower/OpenMP/canonical-loop-trip-count.f90
@@ -92,7 +92,7 @@ subroutine runtime_bounds(lb, ub, step)
! CHECK-NEXT: %[[INCR:.*]] = arith.select %[[IS_DOWNWARDS]], %[[NEG_STEP]], %[[STEP]] : i32
! CHECK-NEXT: %[[LOWER:.*]] = arith.select %[[IS_DOWNWARDS]], %[[UB]], %[[LB]] : i32
! CHECK-NEXT: %[[UPPER:.*]] = arith.select %[[IS_DOWNWARDS]], %[[LB]], %[[UB]] : i32
-! CHECK-NEXT: %[[SPAN:.*]] = arith.subi %[[UPPER]], %[[LOWER]] overflow<nuw> : i32
+! CHECK-NEXT: %[[SPAN:.*]] = arith.subi %[[UPPER]], %[[LOWER]] : i32
! CHECK-NEXT: %[[TC_MINUS_ONE:.*]] = arith.divui %[[SPAN]], %[[INCR]] : i32
! CHECK-NEXT: %[[TC_IF_LOOPING:.*]] = arith.addi %[[TC_MINUS_ONE]], %[[ONE]] overflow<nuw> : i32
! CHECK-NEXT: %[[IS_ZERO_TC:.*]] = arith.cmpi slt, %[[UPPER]], %[[LOWER]] : i32
diff --git a/flang/test/Lower/OpenMP/fuse01.f90 b/flang/test/Lower/OpenMP/fuse01.f90
index a9985b7ffb907..1e05140fc6f31 100644
--- a/flang/test/Lower/OpenMP/fuse01.f90
+++ b/flang/test/Lower/OpenMP/fuse01.f90
@@ -48,7 +48,7 @@ end subroutine omp_fuse01
! CHECK: %[[SELECT_0:.*]] = arith.select %[[CMPI_0]], %[[SUBI_0]], %[[LOAD_2]] : i32
! CHECK: %[[SELECT_1:.*]] = arith.select %[[CMPI_0]], %[[LOAD_1]], %[[LOAD_0]] : i32
! CHECK: %[[SELECT_2:.*]] = arith.select %[[CMPI_0]], %[[LOAD_0]], %[[LOAD_1]] : i32
-! CHECK: %[[SUBI_1:.*]] = arith.subi %[[SELECT_2]], %[[SELECT_1]] overflow<nuw> : i32
+! CHECK: %[[SUBI_1:.*]] = arith.subi %[[SELECT_2]], %[[SELECT_1]] : i32
! CHECK: %[[DIVUI_0:.*]] = arith.divui %[[SUBI_1]], %[[SELECT_0]] : i32
! CHECK: %[[ADDI_0:.*]] = arith.addi %[[DIVUI_0]], %[[CONSTANT_1]] overflow<nuw> : i32
! CHECK: %[[CMPI_1:.*]] = arith.cmpi slt, %[[SELECT_2]], %[[SELECT_1]] : i32
@@ -72,7 +72,7 @@ end subroutine omp_fuse01
! CHECK: %[[SELECT_4:.*]] = arith.select %[[CMPI_2]], %[[SUBI_2]], %[[LOAD_6]] : i32
! CHECK: %[[SELECT_5:.*]] = arith.select %[[CMPI_2]], %[[LOAD_5]], %[[LOAD_4]] : i32
! CHECK: %[[SELECT_6:.*]] = arith.select %[[CMPI_2]], %[[LOAD_4]], %[[LOAD_5]] : i32
-! CHECK: %[[SUBI_3:.*]] = arith.subi %[[SELECT_6]], %[[SELECT_5]] overflow<nuw> : i32
+! CHECK: %[[SUBI_3:.*]] = arith.subi %[[SELECT_6]], %[[SELECT_5]] : i32
! CHECK: %[[DIVUI_1:.*]] = arith.divui %[[SUBI_3]], %[[SELECT_4]] : i32
! CHECK: %[[ADDI_2:.*]] = arith.addi %[[DIVUI_1]], %[[CONSTANT_3]] overflow<nuw> : i32
! CHECK: %[[CMPI_3:.*]] = arith.cmpi slt, %[[SELECT_6]], %[[SELECT_5]] : i32
diff --git a/flang/test/Lower/OpenMP/fuse02.f90 b/flang/test/Lower/OpenMP/fuse02.f90
index 24cc693921566..3e96476653851 100644
--- a/flang/test/Lower/OpenMP/fuse02.f90
+++ b/flang/test/Lower/OpenMP/fuse02.f90
@@ -53,7 +53,7 @@ end subroutine omp_fuse02
! CHECK: %[[SELECT_0:.*]] = arith.select %[[CMPI_0]], %[[SUBI_0]], %[[LOAD_2]] : i32
! CHECK: %[[SELECT_1:.*]] = arith.select %[[CMPI_0]], %[[LOAD_1]], %[[LOAD_0]] : i32
! CHECK: %[[SELECT_2:.*]] = arith.select %[[CMPI_0]], %[[LOAD_0]], %[[LOAD_1]] : i32
-! CHECK: %[[SUBI_1:.*]] = arith.subi %[[SELECT_2]], %[[SELECT_1]] overflow<nuw> : i32
+! CHECK: %[[SUBI_1:.*]] = arith.subi %[[SELECT_2]], %[[SELECT_1]] : i32
! CHECK: %[[DIVUI_0:.*]] = arith.divui %[[SUBI_1]], %[[SELECT_0]] : i32
! CHECK: %[[ADDI_0:.*]] = arith.addi %[[DIVUI_0]], %[[CONSTANT_1]] overflow<nuw> : i32
! CHECK: %[[CMPI_1:.*]] = arith.cmpi slt, %[[SELECT_2]], %[[SELECT_1]] : i32
@@ -77,7 +77,7 @@ end subroutine omp_fuse02
! CHECK: %[[SELECT_4:.*]] = arith.select %[[CMPI_2]], %[[SUBI_2]], %[[LOAD_6]] : i32
! CHECK: %[[SELECT_5:.*]] = arith.select %[[CMPI_2]], %[[LOAD_5]], %[[LOAD_4]] : i32
! CHECK: %[[SELECT_6:.*]] = arith.select %[[CMPI_2]], %[[LOAD_4]], %[[LOAD_5]] : i32
-! CHECK: %[[SUBI_3:.*]] = arith.subi %[[SELECT_6]], %[[SELECT_5]] overflow<nuw> : i32
+! CHECK: %[[SUBI_3:.*]] = arith.subi %[[SELECT_6]], %[[SELECT_5]] : i32
! CHECK: %[[DIVUI_1:.*]] = arith.divui %[[SUBI_3]], %[[SELECT_4]] : i32
! CHECK: %[[ADDI_2:.*]] = arith.addi %[[DIVUI_1]], %[[CONSTANT_3]] overflow<nuw> : i32
! CHECK: %[[CMPI_3:.*]] = arith.cmpi slt, %[[SELECT_6]], %[[SELECT_5]] : i32
@@ -101,7 +101,7 @@ end subroutine omp_fuse02
! CHECK: %[[SELECT_8:.*]] = arith.select %[[CMPI_4]], %[[SUBI_4]], %[[LOAD_10]] : i32
! CHECK: %[[SELECT_9:.*]] = arith.select %[[CMPI_4]], %[[LOAD_9]], %[[LOAD_8]] : i32
! CHECK: %[[SELECT_10:.*]] = arith.select %[[CMPI_4]], %[[LOAD_8]], %[[LOAD_9]] : i32
-! CHECK: %[[SUBI_5:.*]] = arith.subi %[[SELECT_10]], %[[SELECT_9]] overflow<nuw> : i32
+! CHECK: %[[SUBI_5:.*]] = arith.subi %[[SELECT_10]], %[[SELECT_9]] : i32
! CHECK: %[[DIVUI_2:.*]] = arith.divui %[[SUBI_5]], %[[SELECT_8]] : i32
! CHECK: %[[ADDI_4:.*]] = arith.addi %[[DIVUI_2]], %[[CONSTANT_5]] overflow<nuw> : i32
! CHECK: %[[CMPI_5:.*]] = arith.cmpi slt, %[[SELECT_10]], %[[SELECT_9]] : i32
diff --git a/flang/test/Lower/OpenMP/tile01.f90 b/flang/test/Lower/OpenMP/tile01.f90
index fd16bae35c250..7615d7be72905 100644
--- a/flang/test/Lower/OpenMP/tile01.f90
+++ b/flang/test/Lower/OpenMP/tile01.f90
@@ -36,7 +36,7 @@ end subroutine omp_tile01
! CHECK: %[[VAL_16:.*]] = arith.select %[[VAL_14]], %[[VAL_15]], %[[VAL_11]] : i32
! CHECK: %[[VAL_17:.*]] = arith.select %[[VAL_14]], %[[VAL_10]], %[[VAL_9]] : i32
! CHECK: %[[VAL_18:.*]] = arith.select %[[VAL_14]], %[[VAL_9]], %[[VAL_10]] : i32
-! CHECK: %[[VAL_19:.*]] = arith.subi %[[VAL_18]], %[[VAL_17]] overflow<nuw> : i32
+! CHECK: %[[VAL_19:.*]] = arith.subi %[[VAL_18]], %[[VAL_17]] : i32
! CHECK: %[[VAL_20:.*]] = arith.divui %[[VAL_19]], %[[VAL_16]] : i32
! CHECK: %[[VAL_21:.*]] = arith.addi %[[VAL_20]], %[[VAL_13]] overflow<nuw> : i32
! CHECK: %[[VAL_22:.*]] = arith.cmpi slt, %[[VAL_18]], %[[VAL_17]] : i32
diff --git a/flang/test/Lower/OpenMP/tile02.f90 b/flang/test/Lower/OpenMP/tile02.f90
index c87c89f86d8e4..32377caab3c69 100644
--- a/flang/test/Lower/OpenMP/tile02.f90
+++ b/flang/test/Lower/OpenMP/tile02.f90
@@ -41,7 +41,7 @@ end subroutine omp_tile02
! CHECK: %[[VAL_19:.*]] = arith.select %[[VAL_17]], %[[VAL_18]], %[[VAL_14]] : i32
! CHECK: %[[VAL_20:.*]] = arith.select %[[VAL_17]], %[[VAL_13]], %[[VAL_12]] : i32
! CHECK: %[[VAL_21:.*]] = arith.select %[[VAL_17]], %[[VAL_12]], %[[VAL_13]] : i32
-! CHECK: %[[VAL_22:.*]] = arith.subi %[[VAL_21]], %[[VAL_20]] overflow<nuw> : i32
+! CHECK: %[[VAL_22:.*]] = arith.subi %[[VAL_21]], %[[VAL_20]] : i32
! CHECK: %[[VAL_23:.*]] = arith.divui %[[VAL_22]], %[[VAL_19]] : i32
! CHECK: %[[VAL_24:.*]] = arith.addi %[[VAL_23]], %[[VAL_16]] overflow<nuw> : i32
! CHECK: %[[VAL_25:.*]] = arith.cmpi slt, %[[VAL_21]], %[[VAL_20]] : i32
@@ -57,7 +57,7 @@ end subroutine omp_tile02
! CHECK: %[[VAL_35:.*]] = arith.select %[[VAL_33]], %[[VAL_34]], %[[VAL_30]] : i32
! CHECK: %[[VAL_36:.*]] = arith.select %[[VAL_33]], %[[VAL_29]], %[[VAL_28]] : i32
! CHECK: %[[VAL_37:.*]] = arith.select %[[VAL_33]], %[[VAL_28]], %[[VAL_29]] : i32
-! CHECK: %[[VAL_38:.*]] = arith.subi %[[VAL_37]], %[[VAL_36]] overflow<nuw> : i32
+! CHECK: %[[VAL_38:.*]] = arith.subi %[[VAL_37]], %[[VAL_36]] : i32
! CHECK: %[[VAL_39:.*]] = arith.divui %[[VAL_38]], %[[VAL_35]] : i32
! CHECK: %[[VAL_40:.*]] = arith.addi %[[VAL_39]], %[[VAL_32]] overflow<nuw> : i32
! CHECK: %[[VAL_41:.*]] = arith.cmpi slt, %[[VAL_37]], %[[VAL_36]] : i32
diff --git a/flang/test/Lower/OpenMP/unroll-heuristic01.f90 b/flang/test/Lower/OpenMP/unroll-heuristic01.f90
index d050ccb720400..0ee39464943fb 100644
--- a/flang/test/Lower/OpenMP/unroll-heuristic01.f90
+++ b/flang/test/Lower/OpenMP/unroll-heuristic01.f90
@@ -35,7 +35,7 @@ end subroutine omp_unroll_heuristic01
! CHECK: %[[VAL_15:.*]] = arith.select %[[VAL_13]], %[[VAL_14]], %[[VAL_10]] : i32
! CHECK: %[[VAL_16:.*]] = arith.select %[[VAL_13]], %[[VAL_9]], %[[VAL_8]] : i32
! CHECK: %[[VAL_17:.*]] = arith.select %[[VAL_13]], %[[VAL_8]], %[[VAL_9]] : i32
-! CHECK: %[[VAL_18:.*]] = arith.subi %[[VAL_17]], %[[VAL_16]] overflow<nuw> : i32
+! CHECK: %[[VAL_18:.*]] = arith.subi %[[VAL_17]], %[[VAL_16]] : i32
! CHECK: %[[VAL_19:.*]] = arith.divui %[[VAL_18]], %[[VAL_15]] : i32
! CHECK: %[[VAL_20:.*]] = arith.addi %[[VAL_19]], %[[VAL_12]] overflow<nuw> : i32
! CHECK: %[[VAL_21:.*]] = arith.cmpi slt, %[[VAL_17]], %[[VAL_16]] : i32
diff --git a/flang/test/Lower/OpenMP/unroll-heuristic02.f90 b/flang/test/Lower/OpenMP/unroll-heuristic02.f90
index 4164c2c56d7cc..2f5a90e1f2878 100644
--- a/flang/test/Lower/OpenMP/unroll-heuristic02.f90
+++ b/flang/test/Lower/OpenMP/unroll-heuristic02.f90
@@ -47,7 +47,7 @@ end subroutine omp_unroll_heuristic_nested02
!CHECK: %[[VAL_20:.*]] = arith.select %[[VAL_18]], %[[VAL_19]], %[[VAL_15]] : i32
!CHECK: %[[VAL_21:.*]] = arith.select %[[VAL_18]], %[[VAL_14]], %[[VAL_13]] : i32
!CHECK: %[[VAL_22:.*]] = arith.select %[[VAL_18]], %[[VAL_13]], %[[VAL_14]] : i32
-!CHECK: %[[VAL_23:.*]] = arith.subi %[[VAL_22]], %[[VAL_21]] overflow<nuw> : i32
+!CHECK: %[[VAL_23:.*]] = arith.subi %[[VAL_22]], %[[VAL_21]] : i32
!CHECK: %[[VAL_24:.*]] = arith.divui %[[VAL_23]], %[[VAL_20]] : i32
!CHECK: %[[VAL_25:.*]] = arith.addi %[[VAL_24]], %[[VAL_17]] overflow<nuw> : i32
!CHECK: %[[VAL_26:.*]] = arith.cmpi slt, %[[VAL_22]], %[[VAL_21]] : i32
@@ -67,7 +67,7 @@ end subroutine omp_unroll_heuristic_nested02
!CHECK: %[[VAL_39:.*]] = arith.select %[[VAL_37]], %[[VAL_38]], %[[VAL_34]] : i32
!CHECK: %[[VAL_40:.*]] = arith.select %[[VAL_37]], %[[VAL_33]], %[[VAL_32]] : i32
!CHECK: %[[VAL_41:.*]] = arith.select %[[VAL_37]], %[[VAL_32]], %[[VAL_33]] : i32
-!CHECK: %[[VAL_42:.*]] = arith.subi %[[VAL_41]], %[[VAL_40]] overflow<nuw> : i32
+!CHECK: %[[VAL_42:.*]] = arith.subi %[[VAL_41]], %[[VAL_40]] : i32
!CHECK: %[[VAL_43:.*]] = arith.divui %[[VAL_42]], %[[VAL_39]] : i32
!CHECK: %[[VAL_44:.*]] = arith.addi %[[VAL_43]], %[[VAL_36]] overflow<nuw> : i32
!CHECK: %[[VAL_45:.*]] = arith.cmpi slt, %[[VAL_41]], %[[VAL_40]] : i32
diff --git a/flang/test/Lower/OpenMP/unroll-heuristic03.f90 b/flang/test/Lower/OpenMP/unroll-heuristic03.f90
index 1c11b2adc7b61..e004137d65402 100644
--- a/flang/test/Lower/OpenMP/unroll-heuristic03.f90
+++ b/flang/test/Lower/OpenMP/unroll-heuristic03.f90
@@ -40,7 +40,7 @@ end subroutine omp_unroll_heuristic03
! CHECK: %[[VAL_17:.*]] = arith.select %[[VAL_15]], %[[VAL_16]], %[[VAL_12]] : i32
! CHECK: %[[VAL_18:.*]] = arith.select %[[VAL_15]], %[[VAL_11]], %[[VAL_10]] : i32
! CHECK: %[[VAL_19:.*]] = arith.select %[[VAL_15]], %[[VAL_10]], %[[VAL_11]] : i32
-! CHECK: %[[VAL_20:.*]] = arith.subi %[[VAL_19]], %[[VAL_18]] overflow<nuw> : i32
+! CHECK: %[[VAL_20:.*]] = arith.subi %[[VAL_19]], %[[VAL_18]] : i32
! CHECK: %[[VAL_21:.*]] = arith.divui %[[VAL_20]], %[[VAL_17]] : i32
! CHECK: %[[VAL_22:.*]] = arith.addi %[[VAL_21]], %[[VAL_14]] overflow<nuw> : i32
! CHECK: %[[VAL_23:.*]] = arith.cmpi slt, %[[VAL_19]], %[[VAL_18]] : i32
diff --git a/flang/test/Lower/OpenMP/unroll-partial01.f90 b/flang/test/Lower/OpenMP/unroll-partial01.f90
index bad6014270068..b25a41cf19c7e 100644
--- a/flang/test/Lower/OpenMP/unroll-partial01.f90
+++ b/flang/test/Lower/OpenMP/unroll-partial01.f90
@@ -35,7 +35,7 @@ end subroutine omp_unroll_partial01
! CHECK: %[[VAL_15:.*]] = arith.select %[[VAL_13]], %[[VAL_14]], %[[VAL_10]] : i32
! CHECK: %[[VAL_16:.*]] = arith.select %[[VAL_13]], %[[VAL_9]], %[[VAL_8]] : i32
! CHECK: %[[VAL_17:.*]] = arith.select %[[VAL_13]], %[[VAL_8]], %[[VAL_9]] : i32
-! CHECK: %[[VAL_18:.*]] = arith.subi %[[VAL_17]], %[[VAL_16]] overflow<nuw> : i32
+! CHECK: %[[VAL_18:.*]] = arith.subi %[[VAL_17]], %[[VAL_16]] : i32
! CHECK: %[[VAL_19:.*]] = arith.divui %[[VAL_18]], %[[VAL_15]] : i32
! CHECK: %[[VAL_20:.*]] = arith.addi %[[VAL_19]], %[[VAL_12]] overflow<nuw> : i32
! CHECK: %[[VAL_21:.*]] = arith.cmpi slt, %[[VAL_17]], %[[VAL_16]] : i32
More information about the flang-commits
mailing list