Index: flang/lib/Optimizer/CodeGen/CodeGen.cpp =================================================================== --- flang/lib/Optimizer/CodeGen/CodeGen.cpp +++ flang/lib/Optimizer/CodeGen/CodeGen.cpp @@ -1446,6 +1446,7 @@ std::tuple consDescriptorPrefix(BOX box, mlir::Type inputType, mlir::ConversionPatternRewriter &rewriter, unsigned rank, + [[maybe_unused]] mlir::ValueRange substrParams, mlir::ValueRange lenParams, mlir::Value sourceBox = {}, mlir::Type sourceBoxType = {}) const { auto loc = box.getLoc(); @@ -1455,7 +1456,7 @@ llvm::SmallVector typeparams = lenParams; if constexpr (!std::is_same_v) { if (!box.getSubstr().empty() && fir::hasDynamicSize(boxTy.getEleTy())) - typeparams.push_back(box.getSubstr()[1]); + typeparams.push_back(substrParams[1]); } // Write each of the fields with the appropriate values. @@ -1487,6 +1488,7 @@ std::tuple consDescriptorPrefix(fir::cg::XReboxOp box, mlir::Value loweredBox, mlir::ConversionPatternRewriter &rewriter, unsigned rank, + mlir::ValueRange substrParams, mlir::ValueRange lenParams, mlir::Value typeDesc = {}) const { auto loc = box.getLoc(); @@ -1494,7 +1496,7 @@ auto inputBoxTy = box.getBox().getType().dyn_cast(); llvm::SmallVector typeparams = lenParams; if (!box.getSubstr().empty() && fir::hasDynamicSize(boxTy.getEleTy())) - typeparams.push_back(box.getSubstr()[1]); + typeparams.push_back(substrParams[1]); auto [eleSize, cfiTy] = getSizeAndTypeCode(loc, rewriter, boxTy.getEleTy(), typeparams); @@ -1661,8 +1663,8 @@ assert(!embox.getShape() && "There should be no dims on this embox op"); auto [boxTy, dest, eleSize] = consDescriptorPrefix( embox, fir::unwrapRefType(embox.getMemref().getType()), rewriter, - /*rank=*/0, /*lenParams=*/operands.drop_front(1), sourceBox, - sourceBoxType); + /*rank=*/0, /*substrParams=*/mlir::ValueRange{}, + adaptor.getTypeparams(), sourceBox, sourceBoxType); dest = insertBaseAddress(rewriter, embox.getLoc(), dest, operands[0]); if (fir::isDerivedTypeWithLenParams(boxTy)) { TODO(embox.getLoc(), @@ -1692,7 +1694,7 @@ } auto [boxTy, dest, eleSize] = consDescriptorPrefix( xbox, fir::unwrapRefType(xbox.getMemref().getType()), rewriter, - xbox.getOutRank(), operands.drop_front(xbox.lenParamOffset()), + xbox.getOutRank(), adaptor.getSubstr(), adaptor.getLenParams(), sourceBox, sourceBoxType); // Generate the triples in the dims field of the descriptor auto i64Ty = mlir::IntegerType::get(xbox.getContext(), 64); @@ -1915,7 +1917,7 @@ auto [boxTy, dest, eleSize] = consDescriptorPrefix(rebox, loweredBox, rewriter, rebox.getOutRank(), - lenParams, typeDescAddr); + adaptor.getSubstr(), lenParams, typeDescAddr); // Read input extents, strides, and base address llvm::SmallVector inputExtents; Index: flang/test/Fir/embox-substring.fir =================================================================== --- /dev/null +++ flang/test/Fir/embox-substring.fir @@ -0,0 +1,13 @@ +// RUN: fir-opt -o - -cg-rewrite --fir-to-llvm-ir %s | FileCheck %s +// RUN: tco -o - -cg-rewrite --fir-to-llvm-ir %s | FileCheck %s + +// CHECK-LABEL: llvm.func @embox_index_substr( +// CHECK-NOT: NULL_VALUE +// CHECK-NOT: NULL_TYPE +func.func @embox_index_substr(%addr : !fir.ref>>) { + %0 = arith.constant 0 : index + %1 = fir.shape_shift %0, %0 : (index, index) -> !fir.shapeshift<1> + %2 = fir.slice %0, %0, %0 substr %0, %0: (index, index, index, index, index) -> !fir.slice<1> + %3 = fir.embox %addr (%1) [%2] : (!fir.ref>>, !fir.shapeshift<1>, !fir.slice<1>) -> !fir.box>> + return +} Index: flang/test/Fir/rebox-susbtring.fir =================================================================== --- flang/test/Fir/rebox-susbtring.fir +++ flang/test/Fir/rebox-susbtring.fir @@ -65,3 +65,23 @@ fir.call @bar(%2) : (!fir.box>>) -> () return } + +// Test that a rebox with `index` substring parameter is converted +// to legal IR. It used to produce: +// %63 = "llvm.mul"(%62, <>) : (i64, <>) -> i64 +// because the substr was not accessed via the adaptor's operands. + +// CHECK-LABEL: llvm.func @index_substr( +// CHECK-NOT: NULL_VALUE +// CHECK-NOT: NULL_TYPE +func.func @index_substr(%arg0: !fir.box>>) { + %c7_index = arith.constant 7 : index + %c1_i64 = arith.constant 1 : i64 + %c0 = arith.constant 0 : index + %c1 = arith.constant 1 : index + %0:3 = fir.box_dims %arg0, %c0 : (!fir.box>>, index) -> (index, index, index) + %1 = fir.slice %c1, %0#1, %c1_i64 substr %c1_i64, %c7_index : (index, index, i64, i64, index) -> !fir.slice<1> + %2 = fir.rebox %arg0 [%1] : (!fir.box>>, !fir.slice<1>) -> !fir.box>> + fir.call @bar(%2) : (!fir.box>>) -> () + return +}