[flang-commits] [flang] 6e94ad0 - [flang] Fold x + 0, 0 + x and x - 0 for INTEGER and UNSIGNED (#192479)
via flang-commits
flang-commits at lists.llvm.org
Fri Apr 17 09:00:35 PDT 2026
Author: Krzysztof Parzyszek
Date: 2026-04-17T11:00:30-05:00
New Revision: 6e94ad04a118cf7113463715900b772d77247bce
URL: https://github.com/llvm/llvm-project/commit/6e94ad04a118cf7113463715900b772d77247bce
DIFF: https://github.com/llvm/llvm-project/commit/6e94ad04a118cf7113463715900b772d77247bce.diff
LOG: [flang] Fold x + 0, 0 + x and x - 0 for INTEGER and UNSIGNED (#192479)
This fixes https://github.com/llvm/llvm-project/issues/191928.
Added:
flang/test/Evaluate/rewrite09.f90
Modified:
flang/lib/Evaluate/fold-implementation.h
flang/test/Evaluate/rewrite01.f90
flang/test/Lower/HLFIR/array-ctor-as-elemental.f90
flang/test/Lower/HLFIR/array-ctor-as-inlined-temp.f90
flang/test/Lower/HLFIR/array-ctor-as-runtime-temp.f90
Removed:
################################################################################
diff --git a/flang/lib/Evaluate/fold-implementation.h b/flang/lib/Evaluate/fold-implementation.h
index d4d7f2b705b3d..2df2b9e5a300b 100644
--- a/flang/lib/Evaluate/fold-implementation.h
+++ b/flang/lib/Evaluate/fold-implementation.h
@@ -2018,6 +2018,25 @@ Expr<T> FoldOperation(FoldingContext &context, Add<T> &&x) {
}
return Expr<T>{Constant<T>{sum.value}};
}
+ } else if constexpr (T::category == TypeCategory::Integer ||
+ T::category == TypeCategory::Unsigned) {
+ if (auto c{GetScalarConstantValue<T>(x.right())}) {
+ if (c->IsZero() && x.left().Rank() == 0) {
+ if (IsVariable(x.left())) {
+ return FoldOperation(context, Parentheses<T>{std::move(x.left())});
+ } else {
+ return std::move(x.left());
+ }
+ }
+ } else if (auto c{GetScalarConstantValue<T>(x.left())}) {
+ if (c->IsZero() && x.right().Rank() == 0) {
+ if (IsVariable(x.right())) {
+ return FoldOperation(context, Parentheses<T>{std::move(x.right())});
+ } else {
+ return std::move(x.right());
+ }
+ }
+ }
}
return Expr<T>{std::move(x)};
}
@@ -2047,6 +2066,17 @@ Expr<T> FoldOperation(FoldingContext &context, Subtract<T> &&x) {
}
return Expr<T>{Constant<T>{
diff erence.value}};
}
+ } else if constexpr (T::category == TypeCategory::Integer ||
+ T::category == TypeCategory::Unsigned) {
+ if (auto c{GetScalarConstantValue<T>(x.right())}) {
+ if (c->IsZero() && x.left().Rank() == 0) {
+ if (IsVariable(x.left())) {
+ return FoldOperation(context, Parentheses<T>{std::move(x.left())});
+ } else {
+ return std::move(x.left());
+ }
+ }
+ }
}
return Expr<T>{std::move(x)};
}
diff --git a/flang/test/Evaluate/rewrite01.f90 b/flang/test/Evaluate/rewrite01.f90
index 0fa3581a3799f..fbbf051246ffe 100644
--- a/flang/test/Evaluate/rewrite01.f90
+++ b/flang/test/Evaluate/rewrite01.f90
@@ -237,7 +237,7 @@ subroutine array_ctor_implied_do_index(x, j)
character(10) :: c
!CHECK: PRINT *, size([INTEGER(4)::(x(1_8:i:1_8),INTEGER(8)::i=1_8,2_8,1_8)])
print *, size([(x(1:i), integer(8)::i=1,2)])
- !CHECK: PRINT *, int(0_8+2_8*(0_8+max((j-1_8+1_8)/1_8,0_8)),kind=4)
+ !CHECK: PRINT *, int(2_8*max((j-1_8+1_8)/1_8,0_8),kind=4)
print *, size([(x(1:j), integer(8)::i=1,2)])
!CHECK: PRINT *, len([(c(i:i),INTEGER(8)::i=1_8,4_8,1_8)])
print *, len([(c(i:i), integer(8)::i = 1,4)])
diff --git a/flang/test/Evaluate/rewrite09.f90 b/flang/test/Evaluate/rewrite09.f90
new file mode 100644
index 0000000000000..fcc975a2d7fa1
--- /dev/null
+++ b/flang/test/Evaluate/rewrite09.f90
@@ -0,0 +1,49 @@
+!RUN: %flang_fc1 -fdebug-unparse -funsigned %s | FileCheck %s --check-prefix=UNPARSE
+
+subroutine f00(x)
+ integer :: x, y, z
+ y = x + 0
+ z = 0 + x
+end
+
+!UNPARSE: SUBROUTINE f00 (x)
+!UNPARSE: INTEGER x, y, z
+!UNPARSE: y=(x)
+!UNPARSE: z=(x)
+!UNPARSE: END SUBROUTINE
+
+subroutine f01(x)
+ integer :: x, y, z
+ y = x - 0
+ z = 0 - x
+end
+
+!UNPARSE: SUBROUTINE f01 (x)
+!UNPARSE: INTEGER x, y, z
+!UNPARSE: y=(x)
+!UNPARSE: z=0_4-x
+!UNPARSE: END SUBROUTINE
+
+subroutine f02(x)
+ unsigned :: x, y, z
+ y = x + 0u
+ z = 0u + x
+end
+
+!UNPARSE: SUBROUTINE f02 (x)
+!UNPARSE: UNSIGNED x, y, z
+!UNPARSE: y=(x)
+!UNPARSE: z=(x)
+!UNPARSE: END SUBROUTINE
+
+subroutine f03(x)
+ unsigned :: x, y, z
+ y = x - 0u
+ z = 0u - x
+end
+
+!UNPARSE: SUBROUTINE f03 (x)
+!UNPARSE: UNSIGNED x, y, z
+!UNPARSE: y=(x)
+!UNPARSE: z=0U_4-x
+!UNPARSE: END SUBROUTINE
diff --git a/flang/test/Lower/HLFIR/array-ctor-as-elemental.f90 b/flang/test/Lower/HLFIR/array-ctor-as-elemental.f90
index f52216d2f558d..54c6fffbbda54 100644
--- a/flang/test/Lower/HLFIR/array-ctor-as-elemental.f90
+++ b/flang/test/Lower/HLFIR/array-ctor-as-elemental.f90
@@ -45,7 +45,6 @@ subroutine test_as_strided_elemental(lb, ub, stride)
! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[DSCOPE]] arg {{[0-9]+}} {uniq_name = "_QFtest_as_strided_elementalElb"} : (!fir.ref<i64>, !fir.dscope) -> (!fir.ref<i64>, !fir.ref<i64>)
! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_2]] dummy_scope %[[DSCOPE]] arg {{[0-9]+}} {uniq_name = "_QFtest_as_strided_elementalEstride"} : (!fir.ref<i64>, !fir.dscope) -> (!fir.ref<i64>, !fir.ref<i64>)
! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_1]] dummy_scope %[[DSCOPE]] arg {{[0-9]+}} {uniq_name = "_QFtest_as_strided_elementalEub"} : (!fir.ref<i64>, !fir.dscope) -> (!fir.ref<i64>, !fir.ref<i64>)
-! CHECK: %[[VAL_6:.*]] = arith.constant 0 : i64
! CHECK: %[[VAL_7:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref<i64>
! CHECK: %[[VAL_8:.*]] = fir.load %[[VAL_3]]#0 : !fir.ref<i64>
! CHECK: %[[VAL_9:.*]] = arith.subi %[[VAL_7]], %[[VAL_8]] : i64
@@ -55,8 +54,7 @@ subroutine test_as_strided_elemental(lb, ub, stride)
! CHECK: %[[VAL_13:.*]] = arith.divsi %[[VAL_11]], %[[VAL_12]] : i64
! CHECK: %[[VAL_14:.*]] = arith.constant 0 : i64
! CHECK: %[[VAL_16:.*]] = arith.maxsi %[[VAL_13]], %[[VAL_14]] : i64
-! CHECK: %[[VAL_17:.*]] = arith.addi %[[VAL_6]], %[[VAL_16]] : i64
-! CHECK: %[[VAL_18:.*]] = fir.convert %[[VAL_17]] : (i64) -> index
+! CHECK: %[[VAL_18:.*]] = fir.convert %[[VAL_16]] : (i64) -> index
! CHECK: %[[VAL_19:.*]] = fir.shape %[[VAL_18]] : (index) -> !fir.shape<1>
! CHECK: %[[VAL_20:.*]] = fir.load %[[VAL_3]]#0 : !fir.ref<i64>
! CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_20]] : (i64) -> index
diff --git a/flang/test/Lower/HLFIR/array-ctor-as-inlined-temp.f90 b/flang/test/Lower/HLFIR/array-ctor-as-inlined-temp.f90
index 6f300b8dfaa43..f7b3020b34717 100644
--- a/flang/test/Lower/HLFIR/array-ctor-as-inlined-temp.f90
+++ b/flang/test/Lower/HLFIR/array-ctor-as-inlined-temp.f90
@@ -115,7 +115,6 @@ subroutine test_implied_do(n)
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<i64> {fir.bindc_name = "n"}) {
! CHECK: %[[VAL_1:.*]] = fir.alloca index
! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %{{[0-9]+}} arg {{[0-9]+}} {uniq_name = "_QFtest_implied_doEn"} : (!fir.ref<i64>, !fir.dscope) -> (!fir.ref<i64>, !fir.ref<i64>)
-! CHECK: %[[VAL_3:.*]] = arith.constant 0 : i64
! CHECK: %[[VAL_4:.*]] = arith.constant 2 : i64
! CHECK: %[[VAL_5:.*]] = fir.load %[[VAL_2]]#0 : !fir.ref<i64>
! CHECK: %[[VAL_6:.*]] = arith.constant 1 : i64
@@ -127,8 +126,7 @@ subroutine test_implied_do(n)
! CHECK: %[[VAL_12:.*]] = arith.constant 0 : i64
! CHECK: %[[VAL_14:.*]] = arith.maxsi %[[VAL_11]], %[[VAL_12]] : i64
! CHECK: %[[VAL_15:.*]] = arith.muli %[[VAL_4]], %[[VAL_14]] : i64
-! CHECK: %[[VAL_16:.*]] = arith.addi %[[VAL_3]], %[[VAL_15]] : i64
-! CHECK: %[[VAL_17:.*]] = fir.convert %[[VAL_16]] : (i64) -> index
+! CHECK: %[[VAL_17:.*]] = fir.convert %[[VAL_15]] : (i64) -> index
! CHECK: %[[VAL_18:.*]] = arith.constant 1 : index
! CHECK: %[[VAL_18B:.*]] = arith.constant 1 : index
! CHECK: fir.store %[[VAL_18]] to %[[VAL_1]] : !fir.ref<index>
@@ -178,7 +176,6 @@ subroutine test_strided_implied_do(lb, ub, stride)
! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %{{[0-9]+}} arg {{[0-9]+}} {uniq_name = "_QFtest_strided_implied_doElb"} : (!fir.ref<i64>, !fir.dscope) -> (!fir.ref<i64>, !fir.ref<i64>)
! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_2]] dummy_scope %{{[0-9]+}} arg {{[0-9]+}} {uniq_name = "_QFtest_strided_implied_doEstride"} : (!fir.ref<i64>, !fir.dscope) -> (!fir.ref<i64>, !fir.ref<i64>)
! CHECK: %[[VAL_6:.*]]:2 = hlfir.declare %[[VAL_1]] dummy_scope %{{[0-9]+}} arg {{[0-9]+}} {uniq_name = "_QFtest_strided_implied_doEub"} : (!fir.ref<i64>, !fir.dscope) -> (!fir.ref<i64>, !fir.ref<i64>)
-! CHECK: %[[VAL_7:.*]] = arith.constant 0 : i64
! CHECK: %[[VAL_8:.*]] = arith.constant 2 : i64
! CHECK: %[[VAL_9:.*]] = fir.load %[[VAL_6]]#0 : !fir.ref<i64>
! CHECK: %[[VAL_10:.*]] = fir.load %[[VAL_4]]#0 : !fir.ref<i64>
@@ -190,8 +187,7 @@ subroutine test_strided_implied_do(lb, ub, stride)
! CHECK: %[[VAL_16:.*]] = arith.constant 0 : i64
! CHECK: %[[VAL_18:.*]] = arith.maxsi %[[VAL_15]], %[[VAL_16]] : i64
! CHECK: %[[VAL_19:.*]] = arith.muli %[[VAL_8]], %[[VAL_18]] : i64
-! CHECK: %[[VAL_20:.*]] = arith.addi %[[VAL_7]], %[[VAL_19]] : i64
-! CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_20]] : (i64) -> index
+! CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_19]] : (i64) -> index
! CHECK: %[[VAL_22:.*]] = arith.constant 1 : index
! CHECK: %[[VAL_22B:.*]] = arith.constant 1 : index
! CHECK: fir.store %[[VAL_22]] to %[[VAL_3]] : !fir.ref<index>
@@ -239,8 +235,6 @@ subroutine test_nested_implied_do(n, m)
! CHECK: %[[VAL_2:.*]] = fir.alloca index
! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_1]] dummy_scope %{{[0-9]+}} arg {{[0-9]+}} {uniq_name = "_QFtest_nested_implied_doEm"} : (!fir.ref<i64>, !fir.dscope) -> (!fir.ref<i64>, !fir.ref<i64>)
! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %{{[0-9]+}} arg {{[0-9]+}} {uniq_name = "_QFtest_nested_implied_doEn"} : (!fir.ref<i64>, !fir.dscope) -> (!fir.ref<i64>, !fir.ref<i64>)
-! CHECK: %[[VAL_5:.*]] = arith.constant 0 : i64
-! CHECK: %[[VAL_6:.*]] = arith.constant 0 : i64
! CHECK: %[[VAL_7:.*]] = fir.load %[[VAL_3]]#0 : !fir.ref<i64>
! CHECK: %[[VAL_8:.*]] = arith.constant 1 : i64
! CHECK: %[[VAL_9:.*]] = arith.subi %[[VAL_7]], %[[VAL_8]] : i64
@@ -250,7 +244,6 @@ subroutine test_nested_implied_do(n, m)
! CHECK: %[[VAL_13:.*]] = arith.divsi %[[VAL_11]], %[[VAL_12]] : i64
! CHECK: %[[VAL_14:.*]] = arith.constant 0 : i64
! CHECK: %[[VAL_16:.*]] = arith.maxsi %[[VAL_13]], %[[VAL_14]] : i64
-! CHECK: %[[VAL_17:.*]] = arith.addi %[[VAL_6]], %[[VAL_16]] : i64
! CHECK: %[[VAL_18:.*]] = fir.load %[[VAL_4]]#0 : !fir.ref<i64>
! CHECK: %[[VAL_19:.*]] = arith.constant 1 : i64
! CHECK: %[[VAL_20:.*]] = arith.subi %[[VAL_18]], %[[VAL_19]] : i64
@@ -260,9 +253,8 @@ subroutine test_nested_implied_do(n, m)
! CHECK: %[[VAL_24:.*]] = arith.divsi %[[VAL_22]], %[[VAL_23]] : i64
! CHECK: %[[VAL_25:.*]] = arith.constant 0 : i64
! CHECK: %[[VAL_27:.*]] = arith.maxsi %[[VAL_24]], %[[VAL_25]] : i64
-! CHECK: %[[VAL_28:.*]] = arith.muli %[[VAL_17]], %[[VAL_27]] : i64
-! CHECK: %[[VAL_29:.*]] = arith.addi %[[VAL_5]], %[[VAL_28]] : i64
-! CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_29]] : (i64) -> index
+! CHECK: %[[VAL_28:.*]] = arith.muli %[[VAL_16]], %[[VAL_27]] : i64
+! CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_28]] : (i64) -> index
! CHECK: %[[VAL_31:.*]] = arith.constant 1 : index
! CHECK: %[[VAL_31B:.*]] = arith.constant 1 : index
! CHECK: fir.store %[[VAL_31]] to %[[VAL_2]] : !fir.ref<index>
diff --git a/flang/test/Lower/HLFIR/array-ctor-as-runtime-temp.f90 b/flang/test/Lower/HLFIR/array-ctor-as-runtime-temp.f90
index 704245caf3d6d..c9248a63e3863 100644
--- a/flang/test/Lower/HLFIR/array-ctor-as-runtime-temp.f90
+++ b/flang/test/Lower/HLFIR/array-ctor-as-runtime-temp.f90
@@ -66,7 +66,6 @@ subroutine test_arrays(a)
! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.array<10xi64> {bindc_name = ".rt.arrayctor.vector"}
! CHECK: %[[VAL_2:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?xi32>>> {bindc_name = ".tmp.arrayctor"}
! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare {{.*}}Ea"
-! CHECK: %[[VAL_4:.*]] = arith.constant 0 : i64
! CHECK: %[[VAL_5:.*]] = arith.constant 0 : index
! CHECK: %[[VAL_6:.*]]:3 = fir.box_dims %[[VAL_3]]#0, %[[VAL_5]] : (!fir.box<!fir.array<?x?xi32>>, index) -> (index, index, index)
! CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_6]]#1 : (index) -> i64
@@ -74,8 +73,7 @@ subroutine test_arrays(a)
! CHECK: %[[VAL_9:.*]]:3 = fir.box_dims %[[VAL_3]]#0, %[[VAL_8]] : (!fir.box<!fir.array<?x?xi32>>, index) -> (index, index, index)
! CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_9]]#1 : (index) -> i64
! CHECK: %[[VAL_11:.*]] = arith.muli %[[VAL_7]], %[[VAL_10]] : i64
-! CHECK: %[[VAL_12:.*]] = arith.addi %[[VAL_4]], %[[VAL_11]] : i64
-! CHECK: %[[VAL_20:.*]] = arith.addi %[[VAL_12]], %{{.*}} : i64
+! CHECK: %[[VAL_20:.*]] = arith.addi %[[VAL_11]], %{{.*}} : i64
! CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_20]] : (i64) -> index
! CHECK: %[[VAL_22:.*]] = fir.allocmem !fir.array<?xi32>, %[[VAL_21]] {bindc_name = ".tmp.arrayctor", uniq_name = ""}
! CHECK: %[[VAL_23:.*]] = fir.shape %[[VAL_21]] : (index) -> !fir.shape<1>
More information about the flang-commits
mailing list