[flang-commits] [flang] 7e0ef4a - [Flang] Apply nusw nuw flags on array_coor gep's (#184573)
via flang-commits
flang-commits at lists.llvm.org
Fri Mar 13 04:03:58 PDT 2026
Author: Jack Styles
Date: 2026-03-13T11:03:53Z
New Revision: 7e0ef4a2031d8752280c5cdccd14da5a3b6029f1
URL: https://github.com/llvm/llvm-project/commit/7e0ef4a2031d8752280c5cdccd14da5a3b6029f1
DIFF: https://github.com/llvm/llvm-project/commit/7e0ef4a2031d8752280c5cdccd14da5a3b6029f1.diff
LOG: [Flang] Apply nusw nuw flags on array_coor gep's (#184573)
When generating the LLVM IR, since #110060, `nsw` is applied to
operations when lowering the subscripts. This was, up until now, only
applied to arithmetic, and not the related getelementptr's.
The original Discouse thread noted that NSW helped with vectorisation
later on in the process. Changes to the BasicAA pipeline has led to
vectorisation no longer being applied where wrapping cannot be
guaranteed for array_coor instructions. By applying the `nusw nuw` flags
to the GEP's, this enables vectorisation in the middle end. Supporting
arithmatic instructions will also be marked `nuw` to ensure instcombine
does not remove these flags when transforming instructions.
There does need to be some consideration to the `sub` operations
generated in this process. There are cases, such as when an array is
shifted, where unsigned wrapping may occur due to using negative values.
To protect against this, if an array is shifted, `nuw` won't be applied
to the `sub` operations.
This patch has been verified using the following with no regressions:
- llvm-test-suite
- Fujitsu test suite
- Various Opensource HPC Applications
Original Discourse thread:
https://discourse.llvm.org/t/rfc-add-nsw-flags-to-arithmetic-integer-operations-using-the-option-fno-wrapv/77584
Assisted-by: Codex
Added:
flang/test/Fir/array_coor_nuw_nusw.fir
Modified:
flang/lib/Optimizer/CodeGen/CodeGen.cpp
flang/test/Fir/array-coor.fir
flang/test/Fir/arrexp.fir
flang/test/Fir/convert-nontemporal-to-llvm.fir
flang/test/Fir/convert-to-llvm.fir
flang/test/Fir/tbaa-codegen.fir
flang/test/Fir/tbaa-codegen2.fir
flang/test/Fir/tbaa.fir
flang/test/HLFIR/no-block-merging.fir
flang/test/Integration/OpenMP/map-types-and-sizes.f90
flang/test/Integration/OpenMP/private-global.f90
flang/test/Integration/ivdep.f90
flang/test/Integration/prefetch.f90
Removed:
################################################################################
diff --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
index e917eb7e97b6f..c794865e70f64 100644
--- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp
+++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
@@ -2730,6 +2730,16 @@ struct XArrayCoorOpConversion
baseIsBoxed ? getBoxTypePair(coor.getMemref().getType()) : TypePair{};
mlir::LLVM::IntegerOverflowFlags nsw =
mlir::LLVM::IntegerOverflowFlags::nsw;
+ mlir::LLVM::IntegerOverflowFlags nuw =
+ mlir::LLVM::IntegerOverflowFlags::nuw;
+ // TODO Allow for non-default lower bounds that are positive
+ // We know at compile time this is possible, so could be updated in future
+ // to allow for this, and just exclude non-default lower bounds that are
+ // negative. Currently, all shifted XArrayCoorOp's only have nsw on sub
+ // operations.
+ mlir::LLVM::IntegerOverflowFlags subFlags = isShifted ? nsw : (nsw | nuw);
+ mlir::LLVM::IntegerOverflowFlags addMulFlags = nsw | nuw;
+ mlir::LLVM::GEPNoWrapFlags gepFlags = mlir::LLVM::GEPNoWrapFlags::nusw | mlir::LLVM::GEPNoWrapFlags::nuw;
// For each dimension of the array, generate the offset calculation.
for (unsigned i = 0; i < rank; ++i, ++indexOffset, ++shapeOffset,
@@ -2751,15 +2761,16 @@ struct XArrayCoorOpConversion
step = integerCast(loc, rewriter, idxTy, operands[sliceOffset + 2]);
}
auto idx =
- mlir::LLVM::SubOp::create(rewriter, loc, idxTy, index, lb, nsw);
- mlir::Value
diff =
- mlir::LLVM::MulOp::create(rewriter, loc, idxTy, idx, step, nsw);
+ mlir::LLVM::SubOp::create(rewriter, loc, idxTy, index, lb, subFlags);
+ mlir::Value
diff = mlir::LLVM::MulOp::create(rewriter, loc, idxTy, idx,
+ step, addMulFlags);
if (normalSlice) {
mlir::Value sliceLb =
integerCast(loc, rewriter, idxTy, operands[sliceOffset]);
- auto adj =
- mlir::LLVM::SubOp::create(rewriter, loc, idxTy, sliceLb, lb, nsw);
-
diff = mlir::LLVM::AddOp::create(rewriter, loc, idxTy,
diff , adj, nsw);
+ auto adj = mlir::LLVM::SubOp::create(rewriter, loc, idxTy, sliceLb, lb,
+ subFlags);
+
diff = mlir::LLVM::AddOp::create(rewriter, loc, idxTy,
diff , adj,
+ addMulFlags);
}
// Update the offset given the stride and the zero based index `
diff `
// that was just computed.
@@ -2767,21 +2778,21 @@ struct XArrayCoorOpConversion
// Use stride in bytes from the descriptor.
mlir::Value stride =
getStrideFromBox(loc, baseBoxTyPair, operands[0], i, rewriter);
- auto sc =
- mlir::LLVM::MulOp::create(rewriter, loc, idxTy,
diff , stride, nsw);
- offset =
- mlir::LLVM::AddOp::create(rewriter, loc, idxTy, sc, offset, nsw);
+ auto sc = mlir::LLVM::MulOp::create(rewriter, loc, idxTy,
diff , stride,
+ addMulFlags);
+ offset = mlir::LLVM::AddOp::create(rewriter, loc, idxTy, sc, offset,
+ addMulFlags);
} else {
// Use stride computed at last iteration.
- auto sc =
- mlir::LLVM::MulOp::create(rewriter, loc, idxTy,
diff , prevExt, nsw);
- offset =
- mlir::LLVM::AddOp::create(rewriter, loc, idxTy, sc, offset, nsw);
+ auto sc = mlir::LLVM::MulOp::create(rewriter, loc, idxTy,
diff , prevExt,
+ addMulFlags);
+ offset = mlir::LLVM::AddOp::create(rewriter, loc, idxTy, sc, offset,
+ addMulFlags);
// Compute next stride assuming contiguity of the base array
// (in element number).
auto nextExt = integerCast(loc, rewriter, idxTy, operands[shapeOffset]);
prevExt = mlir::LLVM::MulOp::create(rewriter, loc, idxTy, prevExt,
- nextExt, nsw);
+ nextExt, addMulFlags);
}
}
@@ -2794,7 +2805,7 @@ struct XArrayCoorOpConversion
getBaseAddrFromBox(loc, baseBoxTyPair, operands[0], rewriter);
llvm::SmallVector<mlir::LLVM::GEPArg> args{offset};
auto addr = mlir::LLVM::GEPOp::create(rewriter, loc, llvmPtrTy, byteTy,
- base, args);
+ base, args, gepFlags);
if (coor.getSubcomponent().empty()) {
rewriter.replaceOp(coor, addr);
return mlir::success();
@@ -2819,8 +2830,8 @@ struct XArrayCoorOpConversion
operands.slice(coor.getSubcomponentOperandIndex(),
coor.getSubcomponent().size()));
args.append(indices.begin(), indices.end());
- rewriter.replaceOpWithNewOp<mlir::LLVM::GEPOp>(coor, llvmPtrTy,
- elementType, addr, args);
+ rewriter.replaceOpWithNewOp<mlir::LLVM::GEPOp>(
+ coor, llvmPtrTy, elementType, addr, args, gepFlags);
return mlir::success();
}
@@ -2842,7 +2853,7 @@ struct XArrayCoorOpConversion
auto length = integerCast(loc, rewriter, idxTy,
operands[coor.getLenParamsOperandIndex()]);
offset = mlir::LLVM::MulOp::create(rewriter, loc, idxTy, offset,
- length, nsw);
+ length, addMulFlags);
} else {
TODO(loc, "compute size of derived type with type parameters");
}
@@ -2858,7 +2869,7 @@ struct XArrayCoorOpConversion
args.append(indices.begin(), indices.end());
}
rewriter.replaceOpWithNewOp<mlir::LLVM::GEPOp>(
- coor, llvmPtrTy, gepObjectType, adaptor.getMemref(), args);
+ coor, llvmPtrTy, gepObjectType, adaptor.getMemref(), args, gepFlags);
return mlir::success();
}
};
diff --git a/flang/test/Fir/array-coor.fir b/flang/test/Fir/array-coor.fir
index 2caa727a10c50..bb80299b43915 100644
--- a/flang/test/Fir/array-coor.fir
+++ b/flang/test/Fir/array-coor.fir
@@ -9,15 +9,15 @@ func.func @array_coor_box_value(%29 : !fir.box<!fir.array<2xf64>>,
}
// CHECK-LABEL: define double @array_coor_box_value
-// CHECK: %[[t3:.*]] = sub nsw i64 %{{.*}}, 1
-// CHECK: %[[t4:.*]] = mul nsw i64 %[[t3]], 1
+// CHECK: %[[t3:.*]] = sub nuw nsw i64 %{{.*}}, 1
+// CHECK: %[[t4:.*]] = mul nuw nsw i64 %[[t3]], 1
// CHECK: %[[t5:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, ptr %{{.*}}, i32 0, i32 7, i32 0, i32 2
// CHECK: %[[t6:.*]] = load i64, ptr %[[t5]]
-// CHECK: %[[t7:.*]] = mul nsw i64 %[[t4]], %[[t6]]
-// CHECK: %[[t8:.*]] = add nsw i64 %[[t7]], 0
+// CHECK: %[[t7:.*]] = mul nuw nsw i64 %[[t4]], %[[t6]]
+// CHECK: %[[t8:.*]] = add nuw nsw i64 %[[t7]], 0
// CHECK: %[[t9:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, ptr %{{.*}}, i32 0, i32 0
// CHECK: %[[t10:.*]] = load ptr, ptr %[[t9]]
-// CHECK: %[[t11:.*]] = getelementptr i8, ptr %[[t10]], i64 %[[t8]]
+// CHECK: %[[t11:.*]] = getelementptr nusw nuw i8, ptr %[[t10]], i64 %[[t8]]
// CHECK: %[[t12:.*]] = load double, ptr %[[t11]]
// CHECK: ret double %[[t12]]
@@ -36,10 +36,10 @@ func.func private @take_int(%arg0: !fir.ref<i32>) -> ()
// CHECK-SAME: ptr {{[^%]*}}%[[VAL_0:.*]])
// CHECK: %[[VAL_1:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]], ptr, [1 x i64] }, ptr %[[VAL_0]], i32 0, i32 7, i32 0, i32 2
// CHECK: %[[VAL_2:.*]] = load i64, ptr %[[VAL_1]]
-// CHECK: %[[VAL_3:.*]] = mul nsw i64 1, %[[VAL_2]]
-// CHECK: %[[VAL_4:.*]] = add nsw i64 %[[VAL_3]], 0
+// CHECK: %[[VAL_3:.*]] = mul nuw nsw i64 1, %[[VAL_2]]
+// CHECK: %[[VAL_4:.*]] = add nuw nsw i64 %[[VAL_3]], 0
// CHECK: %[[VAL_5:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]], ptr, [1 x i64] }, ptr %[[VAL_0]], i32 0, i32 0
// CHECK: %[[VAL_6:.*]] = load ptr, ptr %[[VAL_5]]
-// CHECK: %[[VAL_7:.*]] = getelementptr i8, ptr %[[VAL_6]], i64 %[[VAL_4]]
-// CHECK: %[[VAL_8:.*]] = getelementptr %t, ptr %[[VAL_7]], i32 0, i32 1
+// CHECK: %[[VAL_7:.*]] = getelementptr nusw nuw i8, ptr %[[VAL_6]], i64 %[[VAL_4]]
+// CHECK: %[[VAL_8:.*]] = getelementptr nusw nuw %t, ptr %[[VAL_7]], i32 0, i32 1
// CHECK: call void @take_int(ptr %[[VAL_8]])
diff --git a/flang/test/Fir/array_coor_nuw_nusw.fir b/flang/test/Fir/array_coor_nuw_nusw.fir
new file mode 100644
index 0000000000000..f30c42096b17e
--- /dev/null
+++ b/flang/test/Fir/array_coor_nuw_nusw.fir
@@ -0,0 +1,35 @@
+// RUN: fir-opt --fir-to-llvm-ir="target=aarch64-unknown-linux-gnu" %s | FileCheck %s
+
+// Verify when nuw/nusw are added for array coordinate lowering where appropriate.
+
+func.func @ext_array_coor_nuw_eligible(%arg0: !fir.ref<!fir.array<?xi32>>) {
+ %c0 = arith.constant 0 : i64
+ %0 = fircg.ext_array_coor %arg0(%c0) <%c0> : (!fir.ref<!fir.array<?xi32>>, i64, i64) -> !fir.ref<i32>
+ return
+}
+
+// CHECK-LABEL: llvm.func @ext_array_coor_nuw_eligible(
+// CHECK: %[[VAL_0:.*]] = llvm.sub %{{.*}}, %{{.*}} overflow<nsw, nuw> : i64
+// CHECK: %[[VAL_1:.*]] = llvm.mul %[[VAL_0]], %{{.*}} overflow<nsw, nuw> : i64
+// CHECK: %[[VAL_2:.*]] = llvm.mul %[[VAL_1]], %{{.*}} overflow<nsw, nuw> : i64
+// CHECK: %[[VAL_3:.*]] = llvm.add %[[VAL_2]], %{{.*}} overflow<nsw, nuw> : i64
+// CHECK: %{{.*}} = llvm.getelementptr nusw|nuw %{{.*}}[%[[VAL_3]]] : (!llvm.ptr, i64) -> !llvm.ptr, i32
+
+// -----
+
+func.func @ext_array_coor_shifted_nuw_ineligble(%arg0: !fir.ref<!fir.array<?xi32>>) {
+ %extent = arith.constant 10 : i64
+ %shift = arith.constant 1 : i64
+ %idx = arith.constant 3 : i64
+ %0 = fircg.ext_array_coor %arg0(%extent) origin %shift <%idx>
+ : (!fir.ref<!fir.array<?xi32>>, i64, i64, i64) -> !fir.ref<i32>
+ return
+}
+
+// CHECK-LABEL: llvm.func @ext_array_coor_shifted_nuw_ineligble(
+// CHECK: %[[VAL_0:.*]] = llvm.sub %{{.*}}, %{{.*}} overflow<nsw> : i64
+// CHECK: %[[VAL_1:.*]] = llvm.mul %[[VAL_0]], %{{.*}} overflow<nsw, nuw> : i64
+// CHECK: %[[VAL_2:.*]] = llvm.mul %[[VAL_1]], %{{.*}} overflow<nsw, nuw> : i64
+// CHECK: %[[VAL_3:.*]] = llvm.add %[[VAL_2]], %{{.*}} overflow<nsw, nuw> : i64
+// CHECK: %{{.*}} = llvm.getelementptr nusw|nuw %{{.*}}[%[[VAL_3]]] : (!llvm.ptr, i64) -> !llvm.ptr, i32
+
diff --git a/flang/test/Fir/arrexp.fir b/flang/test/Fir/arrexp.fir
index e8ec8ac79e0c2..63d39dd6494b1 100644
--- a/flang/test/Fir/arrexp.fir
+++ b/flang/test/Fir/arrexp.fir
@@ -10,7 +10,7 @@ func.func @f1(%a : !fir.ref<!fir.array<?x?xf32>>, %n : index, %m : index, %o : i
%r = fir.do_loop %j = %p to %m step %c1 iter_args(%v1 = %vIn) -> !fir.array<?x?xf32> {
// CHECK: = icmp sgt
%r = fir.do_loop %i = %o to %n step %c1 iter_args(%v = %v1) -> !fir.array<?x?xf32> {
- // CHECK: %[[AOFF:.*]] = getelementptr float, ptr %[[A]], i64
+ // CHECK: %[[AOFF:.*]] = getelementptr nusw nuw float, ptr %[[A]], i64
// CHECK: store float %[[F]], ptr %[[AOFF]]
%r = fir.array_update %v, %f, %i, %j : (!fir.array<?x?xf32>, f32, index, index) -> !fir.array<?x?xf32>
fir.result %r : !fir.array<?x?xf32>
@@ -35,7 +35,7 @@ func.func @f2(%a : !fir.ref<!fir.array<?x?xf32>>, %b : !fir.ref<!fir.array<?x?xf
%r = fir.do_loop %i = %o to %n step %c1 iter_args(%v = %v1) -> !fir.array<?x?xf32> {
%x = fir.array_fetch %wIn, %i, %j : (!fir.array<?x?xf32>, index, index) -> f32
%y = arith.addf %x, %f : f32
- // CHECK: %[[AOFF:.*]] = getelementptr float, ptr %[[A]], i64
+ // CHECK: %[[AOFF:.*]] = getelementptr nusw nuw float, ptr %[[A]], i64
%r = fir.array_update %v, %y, %i, %j : (!fir.array<?x?xf32>, f32, index, index) -> !fir.array<?x?xf32>
fir.result %r : !fir.array<?x?xf32>
}
@@ -59,7 +59,7 @@ func.func @f3(%a : !fir.ref<!fir.array<?x?xf32>>, %b : !fir.ref<!fir.array<?x?xf
%r = fir.do_loop %i = %o to %n step %c1 iter_args(%v = %v1) -> !fir.array<?x?xf32> {
%x = fir.array_fetch %wIn, %i, %j : (!fir.array<?x?xf32>, index, index) -> f32
%y = arith.addf %x, %f : f32
- // CHECK: %[[AOFF:.*]] = getelementptr float, ptr %[[A]], i64
+ // CHECK: %[[AOFF:.*]] = getelementptr nusw nuw float, ptr %[[A]], i64
%i2 = arith.addi %i, %c1 : index
%r = fir.array_update %v, %y, %i2, %j : (!fir.array<?x?xf32>, f32, index, index) -> !fir.array<?x?xf32>
fir.result %r : !fir.array<?x?xf32>
@@ -86,7 +86,7 @@ func.func @f4(%a : !fir.ref<!fir.array<?x?xf32>>, %b : !fir.ref<!fir.array<?x?xf
%x = fir.array_fetch %wIn, %i, %j : (!fir.array<?x?xf32>, index, index) -> f32
%y = arith.addf %x, %f : f32
%y2 = arith.addf %y, %x2 : f32
- // CHECK: %[[AOFF:.*]] = getelementptr float, ptr %[[A]], i64
+ // CHECK: %[[AOFF:.*]] = getelementptr nusw nuw float, ptr %[[A]], i64
%i2 = arith.addi %i, %c1 : index
%r = fir.array_update %v, %y2, %i2, %j : (!fir.array<?x?xf32>, f32, index, index) -> !fir.array<?x?xf32>
fir.result %r : !fir.array<?x?xf32>
@@ -114,11 +114,11 @@ func.func @f5(%arg0: !fir.box<!fir.array<?xf32>>, %arg1: !fir.box<!fir.array<?xf
%4 = fir.do_loop %arg3 = %c0 to %1 step %c1 iter_args(%arg4 = %2) -> (!fir.array<?xf32>) {
// CHECK: %[[B_STRIDE_GEP:.*]] = getelementptr {{.*}}, ptr %[[B]], i32 0, i32 7, i32 0, i32 2
// CHECK: %[[B_STRIDE:.*]] = load i64, ptr %[[B_STRIDE_GEP]]
- // CHECK: %[[B_DIM_OFFSET:.*]] = mul nsw i64 %{{.*}}, %[[B_STRIDE]]
- // CHECK: %[[B_OFFSET:.*]] = add nsw i64 %[[B_DIM_OFFSET]], 0
+ // CHECK: %[[B_DIM_OFFSET:.*]] = mul nuw nsw i64 %{{.*}}, %[[B_STRIDE]]
+ // CHECK: %[[B_OFFSET:.*]] = add nuw nsw i64 %[[B_DIM_OFFSET]], 0
// CHECK: %[[B_BASE_GEP:.*]] = getelementptr {{.*}}, ptr %{{.*}}, i32 0, i32 0
// CHECK: %[[B_BASE:.*]] = load ptr, ptr %[[B_BASE_GEP]]
- // CHECK: %[[B_VOID_ADDR:.*]] = getelementptr i8, ptr %[[B_BASE]], i64 %[[B_OFFSET]]
+ // CHECK: %[[B_VOID_ADDR:.*]] = getelementptr nusw nuw i8, ptr %[[B_BASE]], i64 %[[B_OFFSET]]
// CHECK: %[[B_VAL:.*]] = load float, ptr %[[B_VOID_ADDR]]
// CHECK: fadd float %[[B_VAL]], %[[F]]
%5 = fir.array_fetch %3, %arg3 : (!fir.array<?xf32>, index) -> f32
@@ -174,7 +174,7 @@ func.func @f7(%arg0: !fir.ref<f32>, %arg1: !fir.box<!fir.array<?xf32>>) {
%0 = fir.shift %c4 : (index) -> !fir.shift<1>
// CHECK: %[[STRIDE_GEP:.*]] = getelementptr {{.*}}, ptr %[[Y]], i32 0, i32 7, i32 0, i32 2
// CHECK: %[[STRIDE:.*]] = load i64, ptr %[[STRIDE_GEP]]
- // CHECK: mul nsw i64 96, %[[STRIDE]]
+ // CHECK: mul nuw nsw i64 96, %[[STRIDE]]
%1 = fir.array_coor %arg1(%0) %c100 : (!fir.box<!fir.array<?xf32>>, !fir.shift<1>, index) -> !fir.ref<f32>
%2 = fir.load %1 : !fir.ref<f32>
fir.store %2 to %arg0 : !fir.ref<f32>
@@ -191,7 +191,7 @@ func.func @f8(%a : !fir.ref<!fir.array<2x2x!fir.type<t{i:i32}>>>, %i : i32) {
%1 = fir.field_index i, !fir.type<t{i:i32}>
%2 = fir.shape %c2, %c2 : (index, index) -> !fir.shape<2>
%3 = fir.slice %c1, %c2, %c1, %c1, %c2, %c1 path %1 : (index, index, index, index, index, index, !fir.field) -> !fir.slice<2>
- // CHECK: %[[GEP:.*]] = getelementptr %t, ptr %[[A]], i64 0, i32 0
+ // CHECK: %[[GEP:.*]] = getelementptr nusw nuw %t, ptr %[[A]], i64 0, i32 0
%4 = fir.array_coor %a(%2) [%3] %c1, %c1 : (!fir.ref<!fir.array<2x2x!fir.type<t{i:i32}>>>, !fir.shape<2>, !fir.slice<2>, index, index) -> !fir.ref<i32>
// CHECK: store i32 %[[I]], ptr %[[GEP]], align 4
fir.store %i to %4 : !fir.ref<i32>
@@ -204,8 +204,8 @@ func.func @f8(%a : !fir.ref<!fir.array<2x2x!fir.type<t{i:i32}>>>, %i : i32) {
func.func @f9(%i: i32, %e : i64, %j: i64, %c: !fir.ref<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.ref<!fir.char<1,?>> {
%s = fir.shape %e, %e : (i64, i64) -> !fir.shape<2>
// CHECK: %[[CAST:.*]] = sext i32 %[[I]] to i64
- // CHECK: %[[OFFSET:.*]] = mul nsw i64 %{{.*}}, %[[CAST]]
- // CHECK: getelementptr i8, ptr %[[C]], i64 %[[OFFSET]]
+ // CHECK: %[[OFFSET:.*]] = mul nuw nsw i64 %{{.*}}, %[[CAST]]
+ // CHECK: getelementptr nusw nuw i8, ptr %[[C]], i64 %[[OFFSET]]
%a = fir.array_coor %c(%s) %j, %j typeparams %i : (!fir.ref<!fir.array<?x?x!fir.char<1,?>>>, !fir.shape<2>, i64, i64, i32) -> !fir.ref<!fir.char<1,?>>
return %a : !fir.ref<!fir.char<1,?>>
}
diff --git a/flang/test/Fir/convert-nontemporal-to-llvm.fir b/flang/test/Fir/convert-nontemporal-to-llvm.fir
index 6fd44591d240f..584f1055b9e4f 100644
--- a/flang/test/Fir/convert-nontemporal-to-llvm.fir
+++ b/flang/test/Fir/convert-nontemporal-to-llvm.fir
@@ -68,11 +68,11 @@
// CHECK: %[[VAL10:.*]] = llvm.mlir.constant(1 : i64) : i64
// CHECK: %[[VAL11:.*]] = llvm.mlir.constant(0 : i64) : i64
// CHECK: %[[VAL12:.*]] = llvm.sub %[[VAL2]], %[[VAL6]] overflow<nsw> : i64
-// CHECK: %[[VAL13:.*]] = llvm.mul %[[VAL12]], %[[VAL10]] overflow<nsw> : i64
-// CHECK: %[[VAL14:.*]] = llvm.mul %[[VAL13]], %[[VAL10]] overflow<nsw> : i64
-// CHECK: %[[VAL15:.*]] = llvm.add %[[VAL14]], %[[VAL11]] overflow<nsw> : i64
-// CHECK: %[[VAL16:.*]] = llvm.mul %[[VAL10]], %[[VAL8]] overflow<nsw> : i64
-// CHECK: %[[VAL17:.*]] = llvm.getelementptr %[[VAL4]][%[[VAL15]]] : (!llvm.ptr, i64) -> !llvm.ptr, i32
+// CHECK: %[[VAL13:.*]] = llvm.mul %[[VAL12]], %[[VAL10]] overflow<nsw, nuw> : i64
+// CHECK: %[[VAL14:.*]] = llvm.mul %[[VAL13]], %[[VAL10]] overflow<nsw, nuw> : i64
+// CHECK: %[[VAL15:.*]] = llvm.add %[[VAL14]], %[[VAL11]] overflow<nsw, nuw> : i64
+// CHECK: %[[VAL16:.*]] = llvm.mul %[[VAL10]], %[[VAL8]] overflow<nsw, nuw> : i64
+// CHECK: %[[VAL17:.*]] = llvm.getelementptr nusw|nuw %[[VAL4]][%[[VAL15]]] : (!llvm.ptr, i64) -> !llvm.ptr, i32
// CHECK: %[[VAL18:.*]] = llvm.load %[[VAL17]] {nontemporal} : !llvm.ptr -> i32
// CHECK: %[[VAL19:.*]] = llvm.load %{{.*}} : !llvm.ptr -> i32
// CHECK: %[[VAL20:.*]] = llvm.add %[[VAL18]], %[[VAL19]] : i32
diff --git a/flang/test/Fir/convert-to-llvm.fir b/flang/test/Fir/convert-to-llvm.fir
index 5764677a7736c..a52043c1bdc63 100644
--- a/flang/test/Fir/convert-to-llvm.fir
+++ b/flang/test/Fir/convert-to-llvm.fir
@@ -2223,11 +2223,11 @@ func.func @ext_array_coor0(%arg0: !fir.ref<!fir.array<?xi32>>) {
// CHECK: %[[C0:.*]] = llvm.mlir.constant(0 : i64) : i64
// CHECK: %[[C1:.*]] = llvm.mlir.constant(1 : i64) : i64
// CHECK: %[[C0_1:.*]] = llvm.mlir.constant(0 : i64) : i64
-// CHECK: %[[IDX:.*]] = llvm.sub %[[C0]], %[[C1]] overflow<nsw> : i64
-// CHECK: %[[DIFF0:.*]] = llvm.mul %[[IDX]], %[[C1]] overflow<nsw> : i64
-// CHECK: %[[SC:.*]] = llvm.mul %[[DIFF0]], %[[C1]] overflow<nsw> : i64
-// CHECK: %[[OFFSET:.*]] = llvm.add %[[SC]], %[[C0_1]] overflow<nsw> : i64
-// CHECK: %{{.*}} = llvm.getelementptr %[[ARG0]][%[[OFFSET]]] : (!llvm.ptr, i64) -> !llvm.ptr, i32
+// CHECK: %[[IDX:.*]] = llvm.sub %[[C0]], %[[C1]] overflow<nsw, nuw> : i64
+// CHECK: %[[DIFF0:.*]] = llvm.mul %[[IDX]], %[[C1]] overflow<nsw, nuw> : i64
+// CHECK: %[[SC:.*]] = llvm.mul %[[DIFF0]], %[[C1]] overflow<nsw, nuw> : i64
+// CHECK: %[[OFFSET:.*]] = llvm.add %[[SC]], %[[C0_1]] overflow<nsw, nuw> : i64
+// CHECK: %{{.*}} = llvm.getelementptr nusw|nuw %[[ARG0]][%[[OFFSET]]] : (!llvm.ptr, i64) -> !llvm.ptr, i32
// Conversion with shift and slice.
@@ -2243,12 +2243,12 @@ func.func @ext_array_coor1(%arg0: !fir.ref<!fir.array<?xi32>>) {
// CHECK: %[[C1:.*]] = llvm.mlir.constant(1 : i64) : i64
// CHECK: %[[C0_1:.*]] = llvm.mlir.constant(0 : i64) : i64
// CHECK: %[[IDX:.*]] = llvm.sub %[[C0]], %[[C0]] overflow<nsw> : i64
-// CHECK: %[[DIFF0:.*]] = llvm.mul %[[IDX]], %[[C0]] overflow<nsw> : i64
+// CHECK: %[[DIFF0:.*]] = llvm.mul %[[IDX]], %[[C0]] overflow<nsw, nuw> : i64
// CHECK: %[[ADJ:.*]] = llvm.sub %[[C0]], %[[C0]] overflow<nsw> : i64
-// CHECK: %[[DIFF1:.*]] = llvm.add %[[DIFF0]], %[[ADJ]] overflow<nsw> : i64
-// CHECK: %[[STRIDE:.*]] = llvm.mul %[[DIFF1]], %[[C1]] overflow<nsw> : i64
-// CHECK: %[[OFFSET:.*]] = llvm.add %[[STRIDE]], %[[C0_1]] overflow<nsw> : i64
-// CHECK: %{{.*}} = llvm.getelementptr %[[ARG0]][%[[OFFSET]]] : (!llvm.ptr, i64) -> !llvm.ptr, i32
+// CHECK: %[[DIFF1:.*]] = llvm.add %[[DIFF0]], %[[ADJ]] overflow<nsw, nuw> : i64
+// CHECK: %[[STRIDE:.*]] = llvm.mul %[[DIFF1]], %[[C1]] overflow<nsw, nuw> : i64
+// CHECK: %[[OFFSET:.*]] = llvm.add %[[STRIDE]], %[[C0_1]] overflow<nsw, nuw> : i64
+// CHECK: %{{.*}} = llvm.getelementptr nusw|nuw %[[ARG0]][%[[OFFSET]]] : (!llvm.ptr, i64) -> !llvm.ptr, i32
// Conversion for a dynamic length char.
@@ -2263,11 +2263,11 @@ func.func @ext_array_coor2(%arg0: !fir.ref<!fir.array<?x!fir.char<1,?>>>) {
// CHECK: %[[C0:.*]] = llvm.mlir.constant(0 : i64) : i64
// CHECK: %[[C1:.*]] = llvm.mlir.constant(1 : i64) : i64
// CHECK: %[[C0_1:.*]] = llvm.mlir.constant(0 : i64) : i64
-// CHECK: %[[IDX:.*]] = llvm.sub %[[C0]], %[[C1]] overflow<nsw> : i64
-// CHECK: %[[DIFF0:.*]] = llvm.mul %[[IDX]], %[[C1]] overflow<nsw> : i64
-// CHECK: %[[SC:.*]] = llvm.mul %[[DIFF0]], %[[C1]] overflow<nsw> : i64
-// CHECK: %[[OFFSET:.*]] = llvm.add %[[SC]], %[[C0_1]] overflow<nsw> : i64
-// CHECK: %{{.*}} = llvm.getelementptr %[[ARG0]][%[[OFFSET]]] : (!llvm.ptr, i64) -> !llvm.ptr, i8
+// CHECK: %[[IDX:.*]] = llvm.sub %[[C0]], %[[C1]] overflow<nsw, nuw> : i64
+// CHECK: %[[DIFF0:.*]] = llvm.mul %[[IDX]], %[[C1]] overflow<nsw, nuw> : i64
+// CHECK: %[[SC:.*]] = llvm.mul %[[DIFF0]], %[[C1]] overflow<nsw, nuw> : i64
+// CHECK: %[[OFFSET:.*]] = llvm.add %[[SC]], %[[C0_1]] overflow<nsw, nuw> : i64
+// CHECK: %{{.*}} = llvm.getelementptr nusw|nuw %[[ARG0]][%[[OFFSET]]] : (!llvm.ptr, i64) -> !llvm.ptr, i8
// Conversion for a `fir.box`.
@@ -2282,15 +2282,15 @@ func.func @ext_array_coor3(%arg0: !fir.box<!fir.array<?xi32>>) {
// CHECK: %[[C0:.*]] = llvm.mlir.constant(0 : i64) : i64
// CHECK: %[[C1:.*]] = llvm.mlir.constant(1 : i64) : i64
// CHECK: %[[C0_1:.*]] = llvm.mlir.constant(0 : i64) : i64
-// CHECK: %[[IDX:.*]] = llvm.sub %[[C0]], %[[C1]] overflow<nsw> : i64
-// CHECK: %[[DIFF0:.*]] = llvm.mul %[[IDX]], %[[C1]] overflow<nsw> : i64
+// CHECK: %[[IDX:.*]] = llvm.sub %[[C0]], %[[C1]] overflow<nsw, nuw> : i64
+// CHECK: %[[DIFF0:.*]] = llvm.mul %[[IDX]], %[[C1]] overflow<nsw, nuw> : i64
// CHECK: %[[GEPSTRIDE:.*]] = llvm.getelementptr %[[ARG0]][0, 7, 0, 2] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>
// CHECK: %[[LOADEDSTRIDE:.*]] = llvm.load %[[GEPSTRIDE]] : !llvm.ptr -> i64
-// CHECK: %[[SC:.*]] = llvm.mul %[[DIFF0]], %[[LOADEDSTRIDE]] overflow<nsw> : i64
-// CHECK: %[[OFFSET:.*]] = llvm.add %[[SC]], %[[C0_1]] overflow<nsw> : i64
+// CHECK: %[[SC:.*]] = llvm.mul %[[DIFF0]], %[[LOADEDSTRIDE]] overflow<nsw, nuw> : i64
+// CHECK: %[[OFFSET:.*]] = llvm.add %[[SC]], %[[C0_1]] overflow<nsw, nuw> : i64
// CHECK: %[[GEPADDR:.*]] = llvm.getelementptr %[[ARG0]][0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>
// CHECK: %[[LOADEDADDR:.*]] = llvm.load %[[GEPADDR]] : !llvm.ptr -> !llvm.ptr
-// CHECK: %[[GEPADDROFFSET:.*]] = llvm.getelementptr %[[LOADEDADDR]][%[[OFFSET]]] : (!llvm.ptr, i64) -> !llvm.ptr, i8
+// CHECK: %[[GEPADDROFFSET:.*]] = llvm.getelementptr nusw|nuw %[[LOADEDADDR]][%[[OFFSET]]] : (!llvm.ptr, i64) -> !llvm.ptr, i8
// Conversion with non zero shift and slice.
@@ -2312,12 +2312,12 @@ func.func @ext_array_coor4(%arg0: !fir.ref<!fir.array<100xi32>>) {
// CHECK: %[[C1_1:.*]] = llvm.mlir.constant(1 : i64) : i64
// CHECK: %[[C0_1:.*]] = llvm.mlir.constant(0 : i64) : i64
// CHECK: %[[IDX:.*]] = llvm.sub %[[C1]], %[[C0]] overflow<nsw> : i64
-// CHECK: %[[DIFF0:.*]] = llvm.mul %[[IDX]], %[[C1]] overflow<nsw> : i64
+// CHECK: %[[DIFF0:.*]] = llvm.mul %[[IDX]], %[[C1]] overflow<nsw, nuw> : i64
// CHECK: %[[ADJ:.*]] = llvm.sub %[[C10]], %[[C0]] overflow<nsw> : i64
-// CHECK: %[[DIFF1:.*]] = llvm.add %[[DIFF0]], %[[ADJ]] overflow<nsw> : i64
-// CHECK: %[[STRIDE:.*]] = llvm.mul %[[DIFF1]], %[[C1_1]] overflow<nsw> : i64
-// CHECK: %[[OFFSET:.*]] = llvm.add %[[STRIDE]], %[[C0_1]] overflow<nsw> : i64
-// CHECK: %{{.*}} = llvm.getelementptr %[[ARG0]][%[[OFFSET]]] : (!llvm.ptr, i64) -> !llvm.ptr, i32
+// CHECK: %[[DIFF1:.*]] = llvm.add %[[DIFF0]], %[[ADJ]] overflow<nsw, nuw> : i64
+// CHECK: %[[STRIDE:.*]] = llvm.mul %[[DIFF1]], %[[C1_1]] overflow<nsw, nuw> : i64
+// CHECK: %[[OFFSET:.*]] = llvm.add %[[STRIDE]], %[[C0_1]] overflow<nsw, nuw> : i64
+// CHECK: %{{.*}} = llvm.getelementptr nusw|nuw %[[ARG0]][%[[OFFSET]]] : (!llvm.ptr, i64) -> !llvm.ptr, i32
// Conversion with index type shape and slice
@@ -2330,14 +2330,14 @@ func.func @ext_array_coor5(%arg0: !fir.ref<!fir.array<?xi32>>, %idx1 : index, %i
// CHECK-SAME: %[[VAL_0:.*]]: !llvm.ptr, %[[VAL_1:.*]]: i64, %[[VAL_2:.*]]: i64, %[[VAL_3:.*]]: i64, %[[VAL_4:.*]]: i64, %[[VAL_5:.*]]: i64) {
// CHECK: %[[VAL_6:.*]] = llvm.mlir.constant(1 : i64) : i64
// CHECK: %[[VAL_7:.*]] = llvm.mlir.constant(0 : i64) : i64
-// CHECK: %[[VAL_8:.*]] = llvm.sub %[[VAL_5]], %[[VAL_6]] overflow<nsw> : i64
-// CHECK: %[[VAL_9:.*]] = llvm.mul %[[VAL_8]], %[[VAL_4]] overflow<nsw> : i64
-// CHECK: %[[VAL_10:.*]] = llvm.sub %[[VAL_2]], %[[VAL_6]] overflow<nsw> : i64
-// CHECK: %[[VAL_11:.*]] = llvm.add %[[VAL_9]], %[[VAL_10]] overflow<nsw> : i64
-// CHECK: %[[VAL_12:.*]] = llvm.mul %[[VAL_11]], %[[VAL_6]] overflow<nsw> : i64
-// CHECK: %[[VAL_13:.*]] = llvm.add %[[VAL_12]], %[[VAL_7]] overflow<nsw> : i64
-// CHECK: %[[VAL_14:.*]] = llvm.mul %[[VAL_6]], %[[VAL_1]] overflow<nsw> : i64
-// CHECK: %[[VAL_16:.*]] = llvm.getelementptr %[[VAL_0]][%[[VAL_13]]] : (!llvm.ptr, i64) -> !llvm.ptr, i32
+// CHECK: %[[VAL_8:.*]] = llvm.sub %[[VAL_5]], %[[VAL_6]] overflow<nsw, nuw> : i64
+// CHECK: %[[VAL_9:.*]] = llvm.mul %[[VAL_8]], %[[VAL_4]] overflow<nsw, nuw> : i64
+// CHECK: %[[VAL_10:.*]] = llvm.sub %[[VAL_2]], %[[VAL_6]] overflow<nsw, nuw> : i64
+// CHECK: %[[VAL_11:.*]] = llvm.add %[[VAL_9]], %[[VAL_10]] overflow<nsw, nuw> : i64
+// CHECK: %[[VAL_12:.*]] = llvm.mul %[[VAL_11]], %[[VAL_6]] overflow<nsw, nuw> : i64
+// CHECK: %[[VAL_13:.*]] = llvm.add %[[VAL_12]], %[[VAL_7]] overflow<nsw, nuw> : i64
+// CHECK: %[[VAL_14:.*]] = llvm.mul %[[VAL_6]], %[[VAL_1]] overflow<nsw, nuw> : i64
+// CHECK: %[[VAL_16:.*]] = llvm.getelementptr nusw|nuw %[[VAL_0]][%[[VAL_13]]] : (!llvm.ptr, i64) -> !llvm.ptr, i32
// CHECK: }
// Conversion for 3-d array
@@ -2351,28 +2351,28 @@ func.func @ext_array_coor6(%arg0: !fir.ref<!fir.array<?x?x?xi32>>, %idx1 : index
// CHECK-SAME: %[[VAL_0:.*]]: !llvm.ptr, %[[VAL_1:.*]]: i64, %[[VAL_2:.*]]: i64, %[[VAL_3:.*]]: i64, %[[VAL_4:.*]]: i64, %[[VAL_5:.*]]: i64) {
// CHECK: %[[VAL_6:.*]] = llvm.mlir.constant(1 : i64) : i64
// CHECK: %[[VAL_7:.*]] = llvm.mlir.constant(0 : i64) : i64
-// CHECK: %[[VAL_8:.*]] = llvm.sub %[[VAL_5]], %[[VAL_6]] overflow<nsw> : i64
-// CHECK: %[[VAL_9:.*]] = llvm.mul %[[VAL_8]], %[[VAL_4]] overflow<nsw> : i64
-// CHECK: %[[VAL_10:.*]] = llvm.sub %[[VAL_2]], %[[VAL_6]] overflow<nsw> : i64
-// CHECK: %[[VAL_11:.*]] = llvm.add %[[VAL_9]], %[[VAL_10]] overflow<nsw> : i64
-// CHECK: %[[VAL_12:.*]] = llvm.mul %[[VAL_11]], %[[VAL_6]] overflow<nsw> : i64
-// CHECK: %[[VAL_13:.*]] = llvm.add %[[VAL_12]], %[[VAL_7]] overflow<nsw> : i64
-// CHECK: %[[VAL_14:.*]] = llvm.mul %[[VAL_6]], %[[VAL_1]] overflow<nsw> : i64
-// CHECK: %[[VAL_15:.*]] = llvm.sub %[[VAL_5]], %[[VAL_6]] overflow<nsw> : i64
-// CHECK: %[[VAL_16:.*]] = llvm.mul %[[VAL_15]], %[[VAL_4]] overflow<nsw> : i64
-// CHECK: %[[VAL_17:.*]] = llvm.sub %[[VAL_2]], %[[VAL_6]] overflow<nsw> : i64
-// CHECK: %[[VAL_18:.*]] = llvm.add %[[VAL_16]], %[[VAL_17]] overflow<nsw> : i64
-// CHECK: %[[VAL_19:.*]] = llvm.mul %[[VAL_18]], %[[VAL_14]] overflow<nsw> : i64
-// CHECK: %[[VAL_20:.*]] = llvm.add %[[VAL_19]], %[[VAL_13]] overflow<nsw> : i64
-// CHECK: %[[VAL_21:.*]] = llvm.mul %[[VAL_14]], %[[VAL_1]] overflow<nsw> : i64
-// CHECK: %[[VAL_22:.*]] = llvm.sub %[[VAL_5]], %[[VAL_6]] overflow<nsw> : i64
-// CHECK: %[[VAL_23:.*]] = llvm.mul %[[VAL_22]], %[[VAL_4]] overflow<nsw> : i64
-// CHECK: %[[VAL_24:.*]] = llvm.sub %[[VAL_2]], %[[VAL_6]] overflow<nsw> : i64
-// CHECK: %[[VAL_25:.*]] = llvm.add %[[VAL_23]], %[[VAL_24]] overflow<nsw> : i64
-// CHECK: %[[VAL_26:.*]] = llvm.mul %[[VAL_25]], %[[VAL_21]] overflow<nsw> : i64
-// CHECK: %[[VAL_27:.*]] = llvm.add %[[VAL_26]], %[[VAL_20]] overflow<nsw> : i64
-// CHECK: %[[VAL_28:.*]] = llvm.mul %[[VAL_21]], %[[VAL_1]] overflow<nsw> : i64
-// CHECK: %[[VAL_30:.*]] = llvm.getelementptr %[[VAL_0]][%[[VAL_27]]] : (!llvm.ptr, i64) -> !llvm.ptr, i32
+// CHECK: %[[VAL_8:.*]] = llvm.sub %[[VAL_5]], %[[VAL_6]] overflow<nsw, nuw> : i64
+// CHECK: %[[VAL_9:.*]] = llvm.mul %[[VAL_8]], %[[VAL_4]] overflow<nsw, nuw> : i64
+// CHECK: %[[VAL_10:.*]] = llvm.sub %[[VAL_2]], %[[VAL_6]] overflow<nsw, nuw> : i64
+// CHECK: %[[VAL_11:.*]] = llvm.add %[[VAL_9]], %[[VAL_10]] overflow<nsw, nuw> : i64
+// CHECK: %[[VAL_12:.*]] = llvm.mul %[[VAL_11]], %[[VAL_6]] overflow<nsw, nuw> : i64
+// CHECK: %[[VAL_13:.*]] = llvm.add %[[VAL_12]], %[[VAL_7]] overflow<nsw, nuw> : i64
+// CHECK: %[[VAL_14:.*]] = llvm.mul %[[VAL_6]], %[[VAL_1]] overflow<nsw, nuw> : i64
+// CHECK: %[[VAL_15:.*]] = llvm.sub %[[VAL_5]], %[[VAL_6]] overflow<nsw, nuw> : i64
+// CHECK: %[[VAL_16:.*]] = llvm.mul %[[VAL_15]], %[[VAL_4]] overflow<nsw, nuw> : i64
+// CHECK: %[[VAL_17:.*]] = llvm.sub %[[VAL_2]], %[[VAL_6]] overflow<nsw, nuw> : i64
+// CHECK: %[[VAL_18:.*]] = llvm.add %[[VAL_16]], %[[VAL_17]] overflow<nsw, nuw> : i64
+// CHECK: %[[VAL_19:.*]] = llvm.mul %[[VAL_18]], %[[VAL_14]] overflow<nsw, nuw> : i64
+// CHECK: %[[VAL_20:.*]] = llvm.add %[[VAL_19]], %[[VAL_13]] overflow<nsw, nuw> : i64
+// CHECK: %[[VAL_21:.*]] = llvm.mul %[[VAL_14]], %[[VAL_1]] overflow<nsw, nuw> : i64
+// CHECK: %[[VAL_22:.*]] = llvm.sub %[[VAL_5]], %[[VAL_6]] overflow<nsw, nuw> : i64
+// CHECK: %[[VAL_23:.*]] = llvm.mul %[[VAL_22]], %[[VAL_4]] overflow<nsw, nuw> : i64
+// CHECK: %[[VAL_24:.*]] = llvm.sub %[[VAL_2]], %[[VAL_6]] overflow<nsw, nuw> : i64
+// CHECK: %[[VAL_25:.*]] = llvm.add %[[VAL_23]], %[[VAL_24]] overflow<nsw, nuw> : i64
+// CHECK: %[[VAL_26:.*]] = llvm.mul %[[VAL_25]], %[[VAL_21]] overflow<nsw, nuw> : i64
+// CHECK: %[[VAL_27:.*]] = llvm.add %[[VAL_26]], %[[VAL_20]] overflow<nsw, nuw> : i64
+// CHECK: %[[VAL_28:.*]] = llvm.mul %[[VAL_21]], %[[VAL_1]] overflow<nsw, nuw> : i64
+// CHECK: %[[VAL_30:.*]] = llvm.getelementptr nusw|nuw %[[VAL_0]][%[[VAL_27]]] : (!llvm.ptr, i64) -> !llvm.ptr, i32
// CHECK: llvm.return
// CHECK: }
@@ -2389,14 +2389,14 @@ func.func @ext_array_coor_dt_slice(%arg0: !fir.ref<!fir.array<20x!fir.type<_QFte
// CHECK: %[[VAL_6:.*]] = llvm.mlir.constant(0 : i32) : i32
// CHECK: %[[VAL_7:.*]] = llvm.mlir.constant(1 : i64) : i64
// CHECK: %[[VAL_8:.*]] = llvm.mlir.constant(0 : i64) : i64
-// CHECK: %[[VAL_9:.*]] = llvm.sub %[[VAL_5]], %[[VAL_7]] overflow<nsw> : i64
-// CHECK: %[[VAL_10:.*]] = llvm.mul %[[VAL_9]], %[[VAL_4]] overflow<nsw> : i64
-// CHECK: %[[VAL_11:.*]] = llvm.sub %[[VAL_2]], %[[VAL_7]] overflow<nsw> : i64
-// CHECK: %[[VAL_12:.*]] = llvm.add %[[VAL_10]], %[[VAL_11]] overflow<nsw> : i64
-// CHECK: %[[VAL_13:.*]] = llvm.mul %[[VAL_12]], %[[VAL_7]] overflow<nsw> : i64
-// CHECK: %[[VAL_14:.*]] = llvm.add %[[VAL_13]], %[[VAL_8]] overflow<nsw> : i64
-// CHECK: %[[VAL_15:.*]] = llvm.mul %[[VAL_7]], %[[VAL_1]] overflow<nsw> : i64
-// CHECK: %[[VAL_17:.*]] = llvm.getelementptr %[[VAL_0]][%[[VAL_14]], 0] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.struct<"_QFtest_dt_sliceTt", (i32, i32)>
+// CHECK: %[[VAL_9:.*]] = llvm.sub %[[VAL_5]], %[[VAL_7]] overflow<nsw, nuw> : i64
+// CHECK: %[[VAL_10:.*]] = llvm.mul %[[VAL_9]], %[[VAL_4]] overflow<nsw, nuw> : i64
+// CHECK: %[[VAL_11:.*]] = llvm.sub %[[VAL_2]], %[[VAL_7]] overflow<nsw, nuw> : i64
+// CHECK: %[[VAL_12:.*]] = llvm.add %[[VAL_10]], %[[VAL_11]] overflow<nsw, nuw> : i64
+// CHECK: %[[VAL_13:.*]] = llvm.mul %[[VAL_12]], %[[VAL_7]] overflow<nsw, nuw> : i64
+// CHECK: %[[VAL_14:.*]] = llvm.add %[[VAL_13]], %[[VAL_8]] overflow<nsw, nuw> : i64
+// CHECK: %[[VAL_15:.*]] = llvm.mul %[[VAL_7]], %[[VAL_1]] overflow<nsw, nuw> : i64
+// CHECK: %[[VAL_17:.*]] = llvm.getelementptr nusw|nuw %[[VAL_0]][%[[VAL_14]], 0] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.struct<"_QFtest_dt_sliceTt", (i32, i32)>
// CHECK: llvm.return
// CHECK: }
@@ -2410,7 +2410,7 @@ func.func @ext_array_coor_dt_slice2(%arg0: !fir.ref<!fir.array<2x!fir.type<_QFte
// CHECK-LABEL: llvm.func @ext_array_coor_dt_slice2(
// CHECK-SAME: %[[ARG0:.*]]: !llvm.ptr, %[[IDX1:.*]]: i64, %[[IDX2:.*]]: i64, %[[IDX3:.*]]: i64, %[[IDX4:.*]]: i64, %[[IDX5:.*]]: i64, %[[IDX6:.*]]: i64, %[[IDX7:.*]]: i64) {
-// CHECK: %{{.*}} = llvm.getelementptr %[[ARG0]][%{{.*}}, 0, %[[IDX6]], %[[IDX5]]] : (!llvm.ptr, i64, i64, i64) -> !llvm.ptr, !llvm.struct<"_QFtest_dt_slice2Tt", (array<3 x array<2 x i32>>)>
+// CHECK: %{{.*}} = llvm.getelementptr nusw|nuw %[[ARG0]][%{{.*}}, 0, %[[IDX6]], %[[IDX5]]] : (!llvm.ptr, i64, i64, i64) -> !llvm.ptr, !llvm.struct<"_QFtest_dt_slice2Tt", (array<3 x array<2 x i32>>)>
// CHECK: llvm.return
// CHECK: }
diff --git a/flang/test/Fir/tbaa-codegen.fir b/flang/test/Fir/tbaa-codegen.fir
index b6b0982b3934e..88fabdfb3abed 100644
--- a/flang/test/Fir/tbaa-codegen.fir
+++ b/flang/test/Fir/tbaa-codegen.fir
@@ -31,11 +31,11 @@ module attributes {fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.targ
// CHECK-SAME: ptr {{[^%]*}}%[[ARG0:.*]]){{.*}}{
// [...]
// load a(2):
-// CHECK: %[[VAL20:.*]] = getelementptr i8, ptr %{{.*}}, i64 %{{.*}}
+// CHECK: %[[VAL20:.*]] = getelementptr nusw nuw i8, ptr %{{.*}}, i64 %{{.*}}
// CHECK: %[[A2:.*]] = load i32, ptr %[[VAL20]], align 4, !tbaa ![[A_ACCESS_TAG:.*]]
// [...]
// store a(2) to a(1):
-// CHECK: %[[A1:.*]] = getelementptr i8, ptr %{{.*}}, i64 %{{.*}}
+// CHECK: %[[A1:.*]] = getelementptr nusw nuw i8, ptr %{{.*}}, i64 %{{.*}}
// CHECK: store i32 %[[A2]], ptr %[[A1]], align 4, !tbaa ![[A_ACCESS_TAG]]
// CHECK: ret void
// CHECK: }
diff --git a/flang/test/Fir/tbaa-codegen2.fir b/flang/test/Fir/tbaa-codegen2.fir
index 071d3ec89394c..2228075077bf5 100644
--- a/flang/test/Fir/tbaa-codegen2.fir
+++ b/flang/test/Fir/tbaa-codegen2.fir
@@ -94,11 +94,11 @@ module attributes {fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.targ
// CHECK: %[[VAL40:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, ptr %{{.*}}, i32 0, i32 0
// box access:
// CHECK: %[[VAL41:.*]] = load ptr, ptr %[[VAL40]], align 8, !tbaa ![[BOX_ACCESS_TAG]]
-// CHECK: %[[VAL42:.*]] = getelementptr i8, ptr %[[VAL41]], i64 %{{.*}}
+// CHECK: %[[VAL42:.*]] = getelementptr nusw nuw i8, ptr %[[VAL41]], i64 %{{.*}}
// access to 'a':
// CHECK: %[[VAL43:.*]] = load i32, ptr %[[VAL42]], align 4, !tbaa ![[A_ACCESS_TAG:.*]]
// [...]
-// CHECK: %[[VAL50:.*]] = getelementptr i32, ptr %{{.*}}, i64 %{{.*}}
+// CHECK: %[[VAL50:.*]] = getelementptr nusw nuw i32, ptr %{{.*}}, i64 %{{.*}}
// store to the temporary:
// CHECK: store i32 %{{.*}}, ptr %[[VAL50]], align 4, !tbaa ![[TMP_DATA_ACCESS_TAG:.*]]
// [...]
diff --git a/flang/test/Fir/tbaa.fir b/flang/test/Fir/tbaa.fir
index a494f757613e9..6c9836afae9e8 100644
--- a/flang/test/Fir/tbaa.fir
+++ b/flang/test/Fir/tbaa.fir
@@ -338,15 +338,15 @@ func.func @tbaa(%arg0: !fir.box<!fir.array<?xi32>>) {
// CHECK: %[[VAL_1:.*]] = llvm.mlir.constant(0 : i64) : i64
// CHECK: %[[VAL_2:.*]] = llvm.mlir.constant(1 : i64) : i64
// CHECK: %[[VAL_3:.*]] = llvm.mlir.constant(0 : i64) : i64
-// CHECK: %[[VAL_4:.*]] = llvm.sub %[[VAL_1]], %[[VAL_2]] overflow<nsw> : i64
-// CHECK: %[[VAL_5:.*]] = llvm.mul %[[VAL_4]], %[[VAL_2]] overflow<nsw> : i64
+// CHECK: %[[VAL_4:.*]] = llvm.sub %[[VAL_1]], %[[VAL_2]] overflow<nsw, nuw> : i64
+// CHECK: %[[VAL_5:.*]] = llvm.mul %[[VAL_4]], %[[VAL_2]] overflow<nsw, nuw> : i64
// CHECK: %[[VAL_6:.*]] = llvm.getelementptr %[[VAL_0]][0, 7, 0, 2] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>)>
// CHECK: %[[VAL_7:.*]] = llvm.load %[[VAL_6]] {tbaa = [#[[$BOXT]]]} : !llvm.ptr -> i64
-// CHECK: %[[VAL_8:.*]] = llvm.mul %[[VAL_5]], %[[VAL_7]] overflow<nsw> : i64
-// CHECK: %[[VAL_9:.*]] = llvm.add %[[VAL_8]], %[[VAL_3]] overflow<nsw> : i64
+// CHECK: %[[VAL_8:.*]] = llvm.mul %[[VAL_5]], %[[VAL_7]] overflow<nsw, nuw> : i64
+// CHECK: %[[VAL_9:.*]] = llvm.add %[[VAL_8]], %[[VAL_3]] overflow<nsw, nuw> : i64
// CHECK: %[[VAL_10:.*]] = llvm.getelementptr %[[VAL_0]][0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>)>
// CHECK: %[[VAL_11:.*]] = llvm.load %[[VAL_10]] {tbaa = [#[[$BOXT]]]} : !llvm.ptr -> !llvm.ptr
-// CHECK: %[[VAL_13:.*]] = llvm.getelementptr %[[VAL_11]]{{\[}}%[[VAL_9]]] : (!llvm.ptr, i64) -> !llvm.ptr, i8
+// CHECK: %[[VAL_13:.*]] = llvm.getelementptr nusw|nuw %[[VAL_11]]{{\[}}%[[VAL_9]]] : (!llvm.ptr, i64) -> !llvm.ptr, i8
// CHECK: llvm.return
// CHECK: }
diff --git a/flang/test/HLFIR/no-block-merging.fir b/flang/test/HLFIR/no-block-merging.fir
index 75803bf010884..02deb0cc6c4e5 100644
--- a/flang/test/HLFIR/no-block-merging.fir
+++ b/flang/test/HLFIR/no-block-merging.fir
@@ -27,7 +27,7 @@ func.func @no_shape_merge(%cdt: i1, %from: !fir.ref<!fir.array<?xf64>>, %to : !f
// Note: block merging happens in the output below, but after FIR codegen.
// CHECK-LABEL: define void @no_shape_merge(
-// CHECK: %[[GEP:.*]] = getelementptr i8, ptr %{{.*}}
+// CHECK: %[[GEP:.*]] = getelementptr nusw nuw i8, ptr %{{.*}}
// CHECK: %[[LOAD:.*]] = load double, ptr %[[GEP]]
// CHECK: store double %[[LOAD]], ptr %{{.*}}
// CHECK: ret void
diff --git a/flang/test/Integration/OpenMP/map-types-and-sizes.f90 b/flang/test/Integration/OpenMP/map-types-and-sizes.f90
index ba363b5bc2576..4f11716a85182 100644
--- a/flang/test/Integration/OpenMP/map-types-and-sizes.f90
+++ b/flang/test/Integration/OpenMP/map-types-and-sizes.f90
@@ -816,11 +816,11 @@ end subroutine mapType_common_block_members
!CHECK: %[[GEP_DESC_PTR:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]], ptr, [1 x i64] }, ptr %[[ALLOCA_0]], i32 0, i32 0
!CHECK: %[[SZ_CALC_1:.*]] = load ptr, ptr %[[GEP_DESC_PTR]], align 8
!CHECK: %[[SZ_CALC_2:.*]] = sub nsw i64 2, %[[LOAD_LB]]
-!CHECK: %[[SZ_CALC_3:.*]] = mul nsw i64 %[[SZ_CALC_2]], 1
-!CHECK: %[[SZ_CALC_4:.*]] = mul nsw i64 %[[SZ_CALC_3]], 1
-!CHECK: %[[SZ_CALC_5:.*]] = add nsw i64 %[[SZ_CALC_4]], 0
-!CHECK: %[[SZ_CALC_6:.*]] = mul nsw i64 1, %[[LOAD_UB]]
-!CHECK: %[[SZ_CALC_7:.*]] = getelementptr %_QFmaptype_nested_derived_type_member_idxTvertexes, ptr %[[SZ_CALC_1]], i64 %[[SZ_CALC_5]]
+!CHECK: %[[SZ_CALC_3:.*]] = mul nuw nsw i64 %[[SZ_CALC_2]], 1
+!CHECK: %[[SZ_CALC_4:.*]] = mul nuw nsw i64 %[[SZ_CALC_3]], 1
+!CHECK: %[[SZ_CALC_5:.*]] = add nuw nsw i64 %[[SZ_CALC_4]], 0
+!CHECK: %[[SZ_CALC_6:.*]] = mul nuw nsw i64 1, %[[LOAD_UB]]
+!CHECK: %[[SZ_CALC_7:.*]] = getelementptr nusw nuw %_QFmaptype_nested_derived_type_member_idxTvertexes, ptr %[[SZ_CALC_1]], i64 %[[SZ_CALC_5]]
!CHECK: %[[SZ_CALC_8:.*]] = getelementptr %_QFmaptype_nested_derived_type_member_idxTvertexes, ptr %[[SZ_CALC_7]], i32 0, i32 2
!CHECK: %[[OFF_PTR_4:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, ptr %[[SZ_CALC_8]], i32 0, i32 0
!CHECK: %[[OFF_PTR_CALC_1:.*]] = sub i64 %[[OFF_PTR_CALC_0]], 0
diff --git a/flang/test/Integration/OpenMP/private-global.f90 b/flang/test/Integration/OpenMP/private-global.f90
index 70689d525f986..ed11a95c4aeb1 100644
--- a/flang/test/Integration/OpenMP/private-global.f90
+++ b/flang/test/Integration/OpenMP/private-global.f90
@@ -43,8 +43,8 @@ program bug
! ...
! check that we use the private copy of table for table/=50
! CHECK: omp.par.region3:
-! CHECK: %[[VAL_44:.*]] = sub nsw i64 %{{.*}}, 1
-! CHECK: %[[VAL_45:.*]] = mul nsw i64 %[[VAL_44]], 1
-! CHECK: %[[VAL_46:.*]] = mul nsw i64 %[[VAL_45]], 1
-! CHECK: %[[VAL_47:.*]] = add nsw i64 %[[VAL_46]], 0
-! CHECK: %[[VAL_48:.*]] = getelementptr i32, ptr %[[PRIV_TABLE]], i64 %[[VAL_47]]
+! CHECK: %[[VAL_44:.*]] = sub nuw nsw i64 %{{.*}}, 1
+! CHECK: %[[VAL_45:.*]] = mul nuw nsw i64 %[[VAL_44]], 1
+! CHECK: %[[VAL_46:.*]] = mul nuw nsw i64 %[[VAL_45]], 1
+! CHECK: %[[VAL_47:.*]] = add nuw nsw i64 %[[VAL_46]], 0
+! CHECK: %[[VAL_48:.*]] = getelementptr nusw nuw i32, ptr %[[PRIV_TABLE]], i64 %[[VAL_47]]
diff --git a/flang/test/Integration/ivdep.f90 b/flang/test/Integration/ivdep.f90
index 0be86ffbb0e88..d72ab23af7ad2 100644
--- a/flang/test/Integration/ivdep.f90
+++ b/flang/test/Integration/ivdep.f90
@@ -10,11 +10,11 @@ subroutine ivdep_test1
!CHECK: store i32 {{.*}}, ptr {{.*}}, align 4, !llvm.access.group [[DISTRINCT:.*]]
!CHECK: %[[VAL_8:.*]] = load i32, ptr {{.*}}, align 4, !llvm.access.group [[DISTRINCT]]
!CHECK: %[[VAL_9:.*]] = sext i32 %[[VAL_8]] to i64
- !CHECK: %[[VAL_10:.*]] = sub nsw i64 %[[VAL_9]], 1
- !CHECK: %[[VAL_11:.*]] = mul nsw i64 %[[VAL_10]], 1
- !CHECK: %[[VAL_12:.*]] = mul nsw i64 %[[VAL_11]], 1
- !CHECK: %[[VAL_13:.*]] = add nsw i64 %[[VAL_12]], 0
- !CHECK: %[[VAL_14:.*]] = getelementptr i32, ptr {{.*}}, i64 %[[VAL_13]]
+ !CHECK: %[[VAL_10:.*]] = sub nuw nsw i64 %[[VAL_9]], 1
+ !CHECK: %[[VAL_11:.*]] = mul nuw nsw i64 %[[VAL_10]], 1
+ !CHECK: %[[VAL_12:.*]] = mul nuw nsw i64 %[[VAL_11]], 1
+ !CHECK: %[[VAL_13:.*]] = add nuw nsw i64 %[[VAL_12]], 0
+ !CHECK: %[[VAL_14:.*]] = getelementptr nusw nuw i32, ptr {{.*}}, i64 %[[VAL_13]]
!CHECK: store i32 %[[VAL_8]], ptr %[[VAL_14]], align 4, !llvm.access.group [[DISTRINCT]]
!CHECK: %[[VAL_15:.*]] = load i32, ptr {{.*}}, align 4, !llvm.access.group [[DISTRINCT]]
!CHECK: %[[VAL_16:.*]] = add nsw i32 %[[VAL_15]], 1
@@ -35,24 +35,24 @@ subroutine ivdep_test2
!CHECK: store i32 {{.*}}, ptr {{.*}}, align 4, !llvm.access.group [[DISTRINCT1:.*]]
!CHECK: %[[VAL_10:.*]] = load i32, ptr {{.*}}, align 4, !llvm.access.group [[DISTRINCT1]]
!CHECK: %[[VAL_11:.*]] = sext i32 %[[VAL_10]] to i64
- !CHECK: %[[VAL_12:.*]] = sub nsw i64 %[[VAL_11]], 1
- !CHECK: %[[VAL_13:.*]] = mul nsw i64 %[[VAL_12]], 1
- !CHECK: %[[VAL_14:.*]] = mul nsw i64 %[[VAL_13]], 1
- !CHECK: %[[VAL_15:.*]] = add nsw i64 %[[VAL_14]], 0
- !CHECK: %[[VAL_16:.*]] = getelementptr i32, ptr {{.*}}, i64 %[[VAL_15]]
+ !CHECK: %[[VAL_12:.*]] = sub nuw nsw i64 %[[VAL_11]], 1
+ !CHECK: %[[VAL_13:.*]] = mul nuw nsw i64 %[[VAL_12]], 1
+ !CHECK: %[[VAL_14:.*]] = mul nuw nsw i64 %[[VAL_13]], 1
+ !CHECK: %[[VAL_15:.*]] = add nuw nsw i64 %[[VAL_14]], 0
+ !CHECK: %[[VAL_16:.*]] = getelementptr nusw nuw i32, ptr {{.*}}, i64 %[[VAL_15]]
!CHECK: %[[VAL_17:.*]] = load i32, ptr {{.*}}, align 4, !llvm.access.group [[DISTRINCT1]]
- !CHECK: %[[VAL_18:.*]] = sub nsw i64 %[[VAL_11]], 1
- !CHECK: %[[VAL_19:.*]] = mul nsw i64 %[[VAL_18]], 1
- !CHECK: %[[VAL_20:.*]] = mul nsw i64 %[[VAL_19]], 1
- !CHECK: %[[VAL_21:.*]] = add nsw i64 %[[VAL_20]], 0
- !CHECK: %[[VAL_22:.*]] = getelementptr i32, ptr {{.*}}, i64 %[[VAL_21]]
+ !CHECK: %[[VAL_18:.*]] = sub nuw nsw i64 %[[VAL_11]], 1
+ !CHECK: %[[VAL_19:.*]] = mul nuw nsw i64 %[[VAL_18]], 1
+ !CHECK: %[[VAL_20:.*]] = mul nuw nsw i64 %[[VAL_19]], 1
+ !CHECK: %[[VAL_21:.*]] = add nuw nsw i64 %[[VAL_20]], 0
+ !CHECK: %[[VAL_22:.*]] = getelementptr nusw nuw i32, ptr {{.*}}, i64 %[[VAL_21]]
!CHECK: %[[VAL_23:.*]] = load i32, ptr {{.*}}, align 4, !llvm.access.group [[DISTRINCT1]]
!CHECK: %[[VAL_24:.*]] = add i32 %[[VAL_17]], %[[VAL_23]]
- !CHECK: %[[VAL_25:.*]] = sub nsw i64 %[[VAL_11]], 1
- !CHECK: %[[VAL_26:.*]] = mul nsw i64 %[[VAL_25]], 1
- !CHECK: %[[VAL_27:.*]] = mul nsw i64 %[[VAL_26]], 1
- !CHECK: %[[VAL_28:.*]] = add nsw i64 %[[VAL_27]], 0
- !CHECK: %[[VAL_29:.*]] = getelementptr i32, ptr {{.*}}, i64 %[[VAL_28]]
+ !CHECK: %[[VAL_25:.*]] = sub nuw nsw i64 %[[VAL_11]], 1
+ !CHECK: %[[VAL_26:.*]] = mul nuw nsw i64 %[[VAL_25]], 1
+ !CHECK: %[[VAL_27:.*]] = mul nuw nsw i64 %[[VAL_26]], 1
+ !CHECK: %[[VAL_28:.*]] = add nuw nsw i64 %[[VAL_27]], 0
+ !CHECK: %[[VAL_29:.*]] = getelementptr nusw nuw i32, ptr {{.*}}, i64 %[[VAL_28]]
!CHECK: store i32 %[[VAL_24]], ptr %[[VAL_29]], align 4, !llvm.access.group [[DISTRINCT1]]
!CHECK: %[[VAL_30:.*]] = load i32, ptr {{.*}}, align 4, !llvm.access.group [[DISTRINCT1]]
!CHECK: %[[VAL_31:.*]] = add nsw i32 %[[VAL_30]], 1
@@ -73,24 +73,24 @@ subroutine ivdep_test3
!CHECK: store i32 {{.*}}, ptr {{.*}}, align 4, !llvm.access.group [[DISTRINCT2:.*]]
!CHECK: %[[VAL_10:.*]] = load i32, ptr {{.*}}, align 4, !llvm.access.group [[DISTRINCT2]]
!CHECK: %[[VAL_11:.*]] = sext i32 %[[VAL_10]] to i64
- !CHECK: %[[VAL_12:.*]] = sub nsw i64 %[[VAL_11]], 1
- !CHECK: %[[VAL_13:.*]] = mul nsw i64 %[[VAL_12]], 1
- !CHECK: %[[VAL_14:.*]] = mul nsw i64 %[[VAL_13]], 1
- !CHECK: %[[VAL_15:.*]] = add nsw i64 %[[VAL_14]], 0
- !CHECK: %[[VAL_16:.*]] = getelementptr i32, ptr {{.*}}, i64 %[[VAL_15]]
+ !CHECK: %[[VAL_12:.*]] = sub nuw nsw i64 %[[VAL_11]], 1
+ !CHECK: %[[VAL_13:.*]] = mul nuw nsw i64 %[[VAL_12]], 1
+ !CHECK: %[[VAL_14:.*]] = mul nuw nsw i64 %[[VAL_13]], 1
+ !CHECK: %[[VAL_15:.*]] = add nuw nsw i64 %[[VAL_14]], 0
+ !CHECK: %[[VAL_16:.*]] = getelementptr nusw nuw i32, ptr {{.*}}, i64 %[[VAL_15]]
!CHECK: %[[VAL_17:.*]] = load i32, ptr {{.*}}, align 4, !llvm.access.group [[DISTRINCT2]]
- !CHECK: %[[VAL_18:.*]] = sub nsw i64 %[[VAL_11]], 1
- !CHECK: %[[VAL_19:.*]] = mul nsw i64 %[[VAL_18]], 1
- !CHECK: %[[VAL_20:.*]] = mul nsw i64 %[[VAL_19]], 1
- !CHECK: %[[VAL_21:.*]] = add nsw i64 %[[VAL_20]], 0
- !CHECK: %[[VAL_22:.*]] = getelementptr i32, ptr {{.*}}, i64 %[[VAL_21]]
+ !CHECK: %[[VAL_18:.*]] = sub nuw nsw i64 %[[VAL_11]], 1
+ !CHECK: %[[VAL_19:.*]] = mul nuw nsw i64 %[[VAL_18]], 1
+ !CHECK: %[[VAL_20:.*]] = mul nuw nsw i64 %[[VAL_19]], 1
+ !CHECK: %[[VAL_21:.*]] = add nuw nsw i64 %[[VAL_20]], 0
+ !CHECK: %[[VAL_22:.*]] = getelementptr nusw nuw i32, ptr {{.*}}, i64 %[[VAL_21]]
!CHECK: %[[VAL_23:.*]] = load i32, ptr {{.*}}, align 4, !llvm.access.group [[DISTRINCT2]]
!CHECK: %[[VAL_24:.*]] = add i32 %[[VAL_17]], %[[VAL_23]]
- !CHECK: %[[VAL_25:.*]] = sub nsw i64 %[[VAL_11]], 1
- !CHECK: %[[VAL_26:.*]] = mul nsw i64 %[[VAL_25]], 1
- !CHECK: %[[VAL_27:.*]] = mul nsw i64 %[[VAL_26]], 1
- !CHECK: %[[VAL_28:.*]] = add nsw i64 %[[VAL_27]], 0
- !CHECK: %[[VAL_29:.*]] = getelementptr i32, ptr {{.*}}, i64 %[[VAL_28]]
+ !CHECK: %[[VAL_25:.*]] = sub nuw nsw i64 %[[VAL_11]], 1
+ !CHECK: %[[VAL_26:.*]] = mul nuw nsw i64 %[[VAL_25]], 1
+ !CHECK: %[[VAL_27:.*]] = mul nuw nsw i64 %[[VAL_26]], 1
+ !CHECK: %[[VAL_28:.*]] = add nuw nsw i64 %[[VAL_27]], 0
+ !CHECK: %[[VAL_29:.*]] = getelementptr nusw nuw i32, ptr {{.*}}, i64 %[[VAL_28]]
!CHECK: store i32 %[[VAL_24]], ptr %[[VAL_29]], align 4, !llvm.access.group [[DISTRINCT2]]
!CHECK: call void @_QFivdep_test3Pfoo(), !llvm.access.group [[DISTRINCT2]]
!CHECK: %[[VAL_30:.*]] = load i32, ptr {{.*}}, align 4, !llvm.access.group [[DISTRINCT2]]
diff --git a/flang/test/Integration/prefetch.f90 b/flang/test/Integration/prefetch.f90
index f3fb7a950e328..c015b6736972a 100644
--- a/flang/test/Integration/prefetch.f90
+++ b/flang/test/Integration/prefetch.f90
@@ -28,7 +28,7 @@ subroutine test_prefetch_01()
! LLVM: %[[LOAD_I:.*]] = load i32, ptr %[[VAR_I]], align 4
! LLVM: %{{.*}} = add nsw i32 %[[LOAD_I]], 64
- ! LLVM: %[[GEP_A:.*]] = getelementptr i32, ptr %[[VAR_A]], i64 {{.*}}
+ ! LLVM: %[[GEP_A:.*]] = getelementptr nusw nuw i32, ptr %[[VAR_A]], i64 {{.*}}
! LLVM: call void @llvm.prefetch.p0(ptr %[[GEP_A]], i32 0, i32 3, i32 1)
! LLVM: call void @llvm.prefetch.p0(ptr %[[VAR_J]], i32 0, i32 3, i32 1)
More information about the flang-commits
mailing list