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 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(coor, llvmPtrTy, - elementType, addr, args); + rewriter.replaceOpWithNewOp( + 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( - 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>, } // 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) -> () // 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>) { + %c0 = arith.constant 0 : i64 + %0 = fircg.ext_array_coor %arg0(%c0) <%c0> : (!fir.ref>, i64, i64) -> !fir.ref + return +} + +// CHECK-LABEL: llvm.func @ext_array_coor_nuw_eligible( +// CHECK: %[[VAL_0:.*]] = llvm.sub %{{.*}}, %{{.*}} overflow : i64 +// CHECK: %[[VAL_1:.*]] = llvm.mul %[[VAL_0]], %{{.*}} overflow : i64 +// CHECK: %[[VAL_2:.*]] = llvm.mul %[[VAL_1]], %{{.*}} overflow : i64 +// CHECK: %[[VAL_3:.*]] = llvm.add %[[VAL_2]], %{{.*}} overflow : 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>) { + %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>, i64, i64, i64) -> !fir.ref + return +} + +// CHECK-LABEL: llvm.func @ext_array_coor_shifted_nuw_ineligble( +// CHECK: %[[VAL_0:.*]] = llvm.sub %{{.*}}, %{{.*}} overflow : i64 +// CHECK: %[[VAL_1:.*]] = llvm.mul %[[VAL_0]], %{{.*}} overflow : i64 +// CHECK: %[[VAL_2:.*]] = llvm.mul %[[VAL_1]], %{{.*}} overflow : i64 +// CHECK: %[[VAL_3:.*]] = llvm.add %[[VAL_2]], %{{.*}} overflow : 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>, %n : index, %m : index, %o : i %r = fir.do_loop %j = %p to %m step %c1 iter_args(%v1 = %vIn) -> !fir.array { // CHECK: = icmp sgt %r = fir.do_loop %i = %o to %n step %c1 iter_args(%v = %v1) -> !fir.array { - // 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, f32, index, index) -> !fir.array fir.result %r : !fir.array @@ -35,7 +35,7 @@ func.func @f2(%a : !fir.ref>, %b : !fir.ref !fir.array { %x = fir.array_fetch %wIn, %i, %j : (!fir.array, 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, f32, index, index) -> !fir.array fir.result %r : !fir.array } @@ -59,7 +59,7 @@ func.func @f3(%a : !fir.ref>, %b : !fir.ref !fir.array { %x = fir.array_fetch %wIn, %i, %j : (!fir.array, 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, f32, index, index) -> !fir.array fir.result %r : !fir.array @@ -86,7 +86,7 @@ func.func @f4(%a : !fir.ref>, %b : !fir.ref, 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, f32, index, index) -> !fir.array fir.result %r : !fir.array @@ -114,11 +114,11 @@ func.func @f5(%arg0: !fir.box>, %arg1: !fir.box (!fir.array) { // 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, index) -> f32 @@ -174,7 +174,7 @@ func.func @f7(%arg0: !fir.ref, %arg1: !fir.box>) { %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.shift<1>, index) -> !fir.ref %2 = fir.load %1 : !fir.ref fir.store %2 to %arg0 : !fir.ref @@ -191,7 +191,7 @@ func.func @f8(%a : !fir.ref>>, %i : i32) { %1 = fir.field_index i, !fir.type %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.shape<2>, !fir.slice<2>, index, index) -> !fir.ref // CHECK: store i32 %[[I]], ptr %[[GEP]], align 4 fir.store %i to %4 : !fir.ref @@ -204,8 +204,8 @@ func.func @f8(%a : !fir.ref>>, %i : i32) { func.func @f9(%i: i32, %e : i64, %j: i64, %c: !fir.ref>>) -> !fir.ref> { %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.shape<2>, i64, i64, i32) -> !fir.ref> return %a : !fir.ref> } 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 : i64 -// CHECK: %[[VAL13:.*]] = llvm.mul %[[VAL12]], %[[VAL10]] overflow : i64 -// CHECK: %[[VAL14:.*]] = llvm.mul %[[VAL13]], %[[VAL10]] overflow : i64 -// CHECK: %[[VAL15:.*]] = llvm.add %[[VAL14]], %[[VAL11]] overflow : i64 -// CHECK: %[[VAL16:.*]] = llvm.mul %[[VAL10]], %[[VAL8]] overflow : i64 -// CHECK: %[[VAL17:.*]] = llvm.getelementptr %[[VAL4]][%[[VAL15]]] : (!llvm.ptr, i64) -> !llvm.ptr, i32 +// CHECK: %[[VAL13:.*]] = llvm.mul %[[VAL12]], %[[VAL10]] overflow : i64 +// CHECK: %[[VAL14:.*]] = llvm.mul %[[VAL13]], %[[VAL10]] overflow : i64 +// CHECK: %[[VAL15:.*]] = llvm.add %[[VAL14]], %[[VAL11]] overflow : i64 +// CHECK: %[[VAL16:.*]] = llvm.mul %[[VAL10]], %[[VAL8]] overflow : 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>) { // 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 : i64 -// CHECK: %[[DIFF0:.*]] = llvm.mul %[[IDX]], %[[C1]] overflow : i64 -// CHECK: %[[SC:.*]] = llvm.mul %[[DIFF0]], %[[C1]] overflow : i64 -// CHECK: %[[OFFSET:.*]] = llvm.add %[[SC]], %[[C0_1]] overflow : i64 -// CHECK: %{{.*}} = llvm.getelementptr %[[ARG0]][%[[OFFSET]]] : (!llvm.ptr, i64) -> !llvm.ptr, i32 +// CHECK: %[[IDX:.*]] = llvm.sub %[[C0]], %[[C1]] overflow : i64 +// CHECK: %[[DIFF0:.*]] = llvm.mul %[[IDX]], %[[C1]] overflow : i64 +// CHECK: %[[SC:.*]] = llvm.mul %[[DIFF0]], %[[C1]] overflow : i64 +// CHECK: %[[OFFSET:.*]] = llvm.add %[[SC]], %[[C0_1]] overflow : 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>) { // CHECK: %[[C1:.*]] = llvm.mlir.constant(1 : i64) : i64 // CHECK: %[[C0_1:.*]] = llvm.mlir.constant(0 : i64) : i64 // CHECK: %[[IDX:.*]] = llvm.sub %[[C0]], %[[C0]] overflow : i64 -// CHECK: %[[DIFF0:.*]] = llvm.mul %[[IDX]], %[[C0]] overflow : i64 +// CHECK: %[[DIFF0:.*]] = llvm.mul %[[IDX]], %[[C0]] overflow : i64 // CHECK: %[[ADJ:.*]] = llvm.sub %[[C0]], %[[C0]] overflow : i64 -// CHECK: %[[DIFF1:.*]] = llvm.add %[[DIFF0]], %[[ADJ]] overflow : i64 -// CHECK: %[[STRIDE:.*]] = llvm.mul %[[DIFF1]], %[[C1]] overflow : i64 -// CHECK: %[[OFFSET:.*]] = llvm.add %[[STRIDE]], %[[C0_1]] overflow : i64 -// CHECK: %{{.*}} = llvm.getelementptr %[[ARG0]][%[[OFFSET]]] : (!llvm.ptr, i64) -> !llvm.ptr, i32 +// CHECK: %[[DIFF1:.*]] = llvm.add %[[DIFF0]], %[[ADJ]] overflow : i64 +// CHECK: %[[STRIDE:.*]] = llvm.mul %[[DIFF1]], %[[C1]] overflow : i64 +// CHECK: %[[OFFSET:.*]] = llvm.add %[[STRIDE]], %[[C0_1]] overflow : 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>>) { // 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 : i64 -// CHECK: %[[DIFF0:.*]] = llvm.mul %[[IDX]], %[[C1]] overflow : i64 -// CHECK: %[[SC:.*]] = llvm.mul %[[DIFF0]], %[[C1]] overflow : i64 -// CHECK: %[[OFFSET:.*]] = llvm.add %[[SC]], %[[C0_1]] overflow : i64 -// CHECK: %{{.*}} = llvm.getelementptr %[[ARG0]][%[[OFFSET]]] : (!llvm.ptr, i64) -> !llvm.ptr, i8 +// CHECK: %[[IDX:.*]] = llvm.sub %[[C0]], %[[C1]] overflow : i64 +// CHECK: %[[DIFF0:.*]] = llvm.mul %[[IDX]], %[[C1]] overflow : i64 +// CHECK: %[[SC:.*]] = llvm.mul %[[DIFF0]], %[[C1]] overflow : i64 +// CHECK: %[[OFFSET:.*]] = llvm.add %[[SC]], %[[C0_1]] overflow : 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>) { // 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 : i64 -// CHECK: %[[DIFF0:.*]] = llvm.mul %[[IDX]], %[[C1]] overflow : i64 +// CHECK: %[[IDX:.*]] = llvm.sub %[[C0]], %[[C1]] overflow : i64 +// CHECK: %[[DIFF0:.*]] = llvm.mul %[[IDX]], %[[C1]] overflow : 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 : i64 -// CHECK: %[[OFFSET:.*]] = llvm.add %[[SC]], %[[C0_1]] overflow : i64 +// CHECK: %[[SC:.*]] = llvm.mul %[[DIFF0]], %[[LOADEDSTRIDE]] overflow : i64 +// CHECK: %[[OFFSET:.*]] = llvm.add %[[SC]], %[[C0_1]] overflow : 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>) { // 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 : i64 -// CHECK: %[[DIFF0:.*]] = llvm.mul %[[IDX]], %[[C1]] overflow : i64 +// CHECK: %[[DIFF0:.*]] = llvm.mul %[[IDX]], %[[C1]] overflow : i64 // CHECK: %[[ADJ:.*]] = llvm.sub %[[C10]], %[[C0]] overflow : i64 -// CHECK: %[[DIFF1:.*]] = llvm.add %[[DIFF0]], %[[ADJ]] overflow : i64 -// CHECK: %[[STRIDE:.*]] = llvm.mul %[[DIFF1]], %[[C1_1]] overflow : i64 -// CHECK: %[[OFFSET:.*]] = llvm.add %[[STRIDE]], %[[C0_1]] overflow : i64 -// CHECK: %{{.*}} = llvm.getelementptr %[[ARG0]][%[[OFFSET]]] : (!llvm.ptr, i64) -> !llvm.ptr, i32 +// CHECK: %[[DIFF1:.*]] = llvm.add %[[DIFF0]], %[[ADJ]] overflow : i64 +// CHECK: %[[STRIDE:.*]] = llvm.mul %[[DIFF1]], %[[C1_1]] overflow : i64 +// CHECK: %[[OFFSET:.*]] = llvm.add %[[STRIDE]], %[[C0_1]] overflow : 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>, %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 : i64 -// CHECK: %[[VAL_9:.*]] = llvm.mul %[[VAL_8]], %[[VAL_4]] overflow : i64 -// CHECK: %[[VAL_10:.*]] = llvm.sub %[[VAL_2]], %[[VAL_6]] overflow : i64 -// CHECK: %[[VAL_11:.*]] = llvm.add %[[VAL_9]], %[[VAL_10]] overflow : i64 -// CHECK: %[[VAL_12:.*]] = llvm.mul %[[VAL_11]], %[[VAL_6]] overflow : i64 -// CHECK: %[[VAL_13:.*]] = llvm.add %[[VAL_12]], %[[VAL_7]] overflow : i64 -// CHECK: %[[VAL_14:.*]] = llvm.mul %[[VAL_6]], %[[VAL_1]] overflow : 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 : i64 +// CHECK: %[[VAL_9:.*]] = llvm.mul %[[VAL_8]], %[[VAL_4]] overflow : i64 +// CHECK: %[[VAL_10:.*]] = llvm.sub %[[VAL_2]], %[[VAL_6]] overflow : i64 +// CHECK: %[[VAL_11:.*]] = llvm.add %[[VAL_9]], %[[VAL_10]] overflow : i64 +// CHECK: %[[VAL_12:.*]] = llvm.mul %[[VAL_11]], %[[VAL_6]] overflow : i64 +// CHECK: %[[VAL_13:.*]] = llvm.add %[[VAL_12]], %[[VAL_7]] overflow : i64 +// CHECK: %[[VAL_14:.*]] = llvm.mul %[[VAL_6]], %[[VAL_1]] overflow : 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>, %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 : i64 -// CHECK: %[[VAL_9:.*]] = llvm.mul %[[VAL_8]], %[[VAL_4]] overflow : i64 -// CHECK: %[[VAL_10:.*]] = llvm.sub %[[VAL_2]], %[[VAL_6]] overflow : i64 -// CHECK: %[[VAL_11:.*]] = llvm.add %[[VAL_9]], %[[VAL_10]] overflow : i64 -// CHECK: %[[VAL_12:.*]] = llvm.mul %[[VAL_11]], %[[VAL_6]] overflow : i64 -// CHECK: %[[VAL_13:.*]] = llvm.add %[[VAL_12]], %[[VAL_7]] overflow : i64 -// CHECK: %[[VAL_14:.*]] = llvm.mul %[[VAL_6]], %[[VAL_1]] overflow : i64 -// CHECK: %[[VAL_15:.*]] = llvm.sub %[[VAL_5]], %[[VAL_6]] overflow : i64 -// CHECK: %[[VAL_16:.*]] = llvm.mul %[[VAL_15]], %[[VAL_4]] overflow : i64 -// CHECK: %[[VAL_17:.*]] = llvm.sub %[[VAL_2]], %[[VAL_6]] overflow : i64 -// CHECK: %[[VAL_18:.*]] = llvm.add %[[VAL_16]], %[[VAL_17]] overflow : i64 -// CHECK: %[[VAL_19:.*]] = llvm.mul %[[VAL_18]], %[[VAL_14]] overflow : i64 -// CHECK: %[[VAL_20:.*]] = llvm.add %[[VAL_19]], %[[VAL_13]] overflow : i64 -// CHECK: %[[VAL_21:.*]] = llvm.mul %[[VAL_14]], %[[VAL_1]] overflow : i64 -// CHECK: %[[VAL_22:.*]] = llvm.sub %[[VAL_5]], %[[VAL_6]] overflow : i64 -// CHECK: %[[VAL_23:.*]] = llvm.mul %[[VAL_22]], %[[VAL_4]] overflow : i64 -// CHECK: %[[VAL_24:.*]] = llvm.sub %[[VAL_2]], %[[VAL_6]] overflow : i64 -// CHECK: %[[VAL_25:.*]] = llvm.add %[[VAL_23]], %[[VAL_24]] overflow : i64 -// CHECK: %[[VAL_26:.*]] = llvm.mul %[[VAL_25]], %[[VAL_21]] overflow : i64 -// CHECK: %[[VAL_27:.*]] = llvm.add %[[VAL_26]], %[[VAL_20]] overflow : i64 -// CHECK: %[[VAL_28:.*]] = llvm.mul %[[VAL_21]], %[[VAL_1]] overflow : 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 : i64 +// CHECK: %[[VAL_9:.*]] = llvm.mul %[[VAL_8]], %[[VAL_4]] overflow : i64 +// CHECK: %[[VAL_10:.*]] = llvm.sub %[[VAL_2]], %[[VAL_6]] overflow : i64 +// CHECK: %[[VAL_11:.*]] = llvm.add %[[VAL_9]], %[[VAL_10]] overflow : i64 +// CHECK: %[[VAL_12:.*]] = llvm.mul %[[VAL_11]], %[[VAL_6]] overflow : i64 +// CHECK: %[[VAL_13:.*]] = llvm.add %[[VAL_12]], %[[VAL_7]] overflow : i64 +// CHECK: %[[VAL_14:.*]] = llvm.mul %[[VAL_6]], %[[VAL_1]] overflow : i64 +// CHECK: %[[VAL_15:.*]] = llvm.sub %[[VAL_5]], %[[VAL_6]] overflow : i64 +// CHECK: %[[VAL_16:.*]] = llvm.mul %[[VAL_15]], %[[VAL_4]] overflow : i64 +// CHECK: %[[VAL_17:.*]] = llvm.sub %[[VAL_2]], %[[VAL_6]] overflow : i64 +// CHECK: %[[VAL_18:.*]] = llvm.add %[[VAL_16]], %[[VAL_17]] overflow : i64 +// CHECK: %[[VAL_19:.*]] = llvm.mul %[[VAL_18]], %[[VAL_14]] overflow : i64 +// CHECK: %[[VAL_20:.*]] = llvm.add %[[VAL_19]], %[[VAL_13]] overflow : i64 +// CHECK: %[[VAL_21:.*]] = llvm.mul %[[VAL_14]], %[[VAL_1]] overflow : i64 +// CHECK: %[[VAL_22:.*]] = llvm.sub %[[VAL_5]], %[[VAL_6]] overflow : i64 +// CHECK: %[[VAL_23:.*]] = llvm.mul %[[VAL_22]], %[[VAL_4]] overflow : i64 +// CHECK: %[[VAL_24:.*]] = llvm.sub %[[VAL_2]], %[[VAL_6]] overflow : i64 +// CHECK: %[[VAL_25:.*]] = llvm.add %[[VAL_23]], %[[VAL_24]] overflow : i64 +// CHECK: %[[VAL_26:.*]] = llvm.mul %[[VAL_25]], %[[VAL_21]] overflow : i64 +// CHECK: %[[VAL_27:.*]] = llvm.add %[[VAL_26]], %[[VAL_20]] overflow : i64 +// CHECK: %[[VAL_28:.*]] = llvm.mul %[[VAL_21]], %[[VAL_1]] overflow : 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 : i64 -// CHECK: %[[VAL_10:.*]] = llvm.mul %[[VAL_9]], %[[VAL_4]] overflow : i64 -// CHECK: %[[VAL_11:.*]] = llvm.sub %[[VAL_2]], %[[VAL_7]] overflow : i64 -// CHECK: %[[VAL_12:.*]] = llvm.add %[[VAL_10]], %[[VAL_11]] overflow : i64 -// CHECK: %[[VAL_13:.*]] = llvm.mul %[[VAL_12]], %[[VAL_7]] overflow : i64 -// CHECK: %[[VAL_14:.*]] = llvm.add %[[VAL_13]], %[[VAL_8]] overflow : i64 -// CHECK: %[[VAL_15:.*]] = llvm.mul %[[VAL_7]], %[[VAL_1]] overflow : 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 : i64 +// CHECK: %[[VAL_10:.*]] = llvm.mul %[[VAL_9]], %[[VAL_4]] overflow : i64 +// CHECK: %[[VAL_11:.*]] = llvm.sub %[[VAL_2]], %[[VAL_7]] overflow : i64 +// CHECK: %[[VAL_12:.*]] = llvm.add %[[VAL_10]], %[[VAL_11]] overflow : i64 +// CHECK: %[[VAL_13:.*]] = llvm.mul %[[VAL_12]], %[[VAL_7]] overflow : i64 +// CHECK: %[[VAL_14:.*]] = llvm.add %[[VAL_13]], %[[VAL_8]] overflow : i64 +// CHECK: %[[VAL_15:.*]] = llvm.mul %[[VAL_7]], %[[VAL_1]] overflow : 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 !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>) { // 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 : i64 -// CHECK: %[[VAL_5:.*]] = llvm.mul %[[VAL_4]], %[[VAL_2]] overflow : i64 +// CHECK: %[[VAL_4:.*]] = llvm.sub %[[VAL_1]], %[[VAL_2]] overflow : i64 +// CHECK: %[[VAL_5:.*]] = llvm.mul %[[VAL_4]], %[[VAL_2]] overflow : 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 : i64 -// CHECK: %[[VAL_9:.*]] = llvm.add %[[VAL_8]], %[[VAL_3]] overflow : i64 +// CHECK: %[[VAL_8:.*]] = llvm.mul %[[VAL_5]], %[[VAL_7]] overflow : i64 +// CHECK: %[[VAL_9:.*]] = llvm.add %[[VAL_8]], %[[VAL_3]] overflow : 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>, %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)