[flang-commits] [flang] [Flang] Apply nusw nuw flags on array_coor gep's (PR #184573)
via flang-commits
flang-commits at lists.llvm.org
Wed Mar 4 01:31:16 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-fir-hlfir
Author: Jack Styles (Stylie777)
<details>
<summary>Changes</summary>
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.
This is only applied in specific circumstances, where it is deemed safe to assume no unsigned wrapping. Applying in cases where we cannot guarantee no wrapping may lead to mis-compilation, such as slices or dynamic sizes. In these cases, the existing behaviour is applied as per PR #<!-- -->110060.
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
---
Full diff: https://github.com/llvm/llvm-project/pull/184573.diff
7 Files Affected:
- (modified) flang/lib/Optimizer/CodeGen/CodeGen.cpp (+40-20)
- (modified) flang/test/Fir/convert-to-llvm.fir (+8-8)
- (modified) flang/test/Fir/tbaa-codegen2.fir (+1-1)
- (modified) flang/test/HLFIR/no-block-merging.fir (+1-1)
- (modified) flang/test/Integration/OpenMP/private-global.f90 (+4-4)
- (modified) flang/test/Integration/ivdep.f90 (+28-28)
- (modified) flang/test/Integration/prefetch.f90 (+1-1)
``````````diff
diff --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
index 1c5cc3cc1b306..37590e6cb3198 100644
--- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp
+++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
@@ -2713,6 +2713,25 @@ struct XArrayCoorOpConversion
baseIsBoxed ? getBoxTypePair(coor.getMemref().getType()) : TypePair{};
mlir::LLVM::IntegerOverflowFlags nsw =
mlir::LLVM::IntegerOverflowFlags::nsw;
+ mlir::LLVM::IntegerOverflowFlags nuw =
+ mlir::LLVM::IntegerOverflowFlags::nuw;
+ mlir::LLVM::IntegerOverflowFlags subFlags = nsw;
+ mlir::LLVM::IntegerOverflowFlags addMulFlags = nsw;
+ mlir::LLVM::GEPNoWrapFlags gepFlags = mlir::LLVM::GEPNoWrapFlags::none;
+
+ // In certain cases, where unsigned wrapping is known not to not occur, we
+ // can apply the nuw flag to Add/Mul operations, and `nusw nuw` flags to
+ // getelementptr's. By doing so, this enables better optimization through
+ // slp-vectorizer later in the LLVM pipeline.
+ const bool canUseNuw = !baseIsBoxed && !isShifted && !isSliced &&
+ coor.getSubcomponent().empty() &&
+ coor.getLenParams().empty() &&
+ !coor.getShape().empty();
+ if (canUseNuw) {
+ addMulFlags = addMulFlags | nuw;
+ 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,
@@ -2734,15 +2753,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.
@@ -2750,21 +2770,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);
}
}
@@ -2777,7 +2797,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();
@@ -2802,8 +2822,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();
}
@@ -2825,7 +2845,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");
}
@@ -2841,7 +2861,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/convert-to-llvm.fir b/flang/test/Fir/convert-to-llvm.fir
index 4108b3b11e2b9..9c6bbd2f766b0 100644
--- a/flang/test/Fir/convert-to-llvm.fir
+++ b/flang/test/Fir/convert-to-llvm.fir
@@ -2224,10 +2224,10 @@ func.func @ext_array_coor0(%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]], %[[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: %[[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.
@@ -2264,10 +2264,10 @@ func.func @ext_array_coor2(%arg0: !fir.ref<!fir.array<?x!fir.char<1,?>>>) {
// 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: %[[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`.
diff --git a/flang/test/Fir/tbaa-codegen2.fir b/flang/test/Fir/tbaa-codegen2.fir
index 071d3ec89394c..cab258c7a149b 100644
--- a/flang/test/Fir/tbaa-codegen2.fir
+++ b/flang/test/Fir/tbaa-codegen2.fir
@@ -98,7 +98,7 @@ module attributes {fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.targ
// 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/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/private-global.f90 b/flang/test/Integration/OpenMP/private-global.f90
index 978a8fa3c8205..a49ed6000e205 100644
--- a/flang/test/Integration/OpenMP/private-global.f90
+++ b/flang/test/Integration/OpenMP/private-global.f90
@@ -44,7 +44,7 @@ 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_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..00b0279e91d5e 100644
--- a/flang/test/Integration/ivdep.f90
+++ b/flang/test/Integration/ivdep.f90
@@ -11,10 +11,10 @@ subroutine ivdep_test1
!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_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
@@ -36,23 +36,23 @@ subroutine ivdep_test2
!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_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_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_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
@@ -74,23 +74,23 @@ subroutine ivdep_test3
!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_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_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_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)
``````````
</details>
https://github.com/llvm/llvm-project/pull/184573
More information about the flang-commits
mailing list