62 changes: 62 additions & 0 deletions clang/test/Modules/prune-non-affecting-module-map-files.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Check that the presence of non-affecting module map files does not affect the
// contents of PCM files.

// RUN: rm -rf %t && mkdir %t
// RUN: split-file %s %t

//--- a/module.modulemap
module a {}

//--- b/module.modulemap
module b {}

//--- c/module.modulemap
module c { header "c.h" }
//--- c/c.h
@import b;

//--- tu.m
@import c;

//--- explicit-mms-common-args.rsp
-fmodule-map-file=b/module.modulemap -fmodule-map-file=c/module.modulemap -fmodules -fmodules-cache-path=cache -fdisable-module-hash -fsyntax-only tu.m
//--- implicit-search-args.rsp
-I a -I b -I c -fimplicit-module-maps -fmodules -fmodules-cache-path=cache -fdisable-module-hash -fsyntax-only tu.m
//--- implicit-search-args.rsp-end

// Test with explicit module map files.
//
// RUN: %clang_cc1 -working-directory %t @%t/explicit-mms-common-args.rsp
// RUN: mv %t/cache %t/cache-explicit-no-a-prune
// RUN: %clang_cc1 -working-directory %t @%t/explicit-mms-common-args.rsp -fno-modules-prune-non-affecting-module-map-files
// RUN: mv %t/cache %t/cache-explicit-no-a-keep
//
// RUN: %clang_cc1 -working-directory %t -fmodule-map-file=a/module.modulemap @%t/explicit-mms-common-args.rsp
// RUN: mv %t/cache %t/cache-explicit-a-prune
// RUN: %clang_cc1 -working-directory %t -fmodule-map-file=a/module.modulemap @%t/explicit-mms-common-args.rsp -fno-modules-prune-non-affecting-module-map-files
// RUN: mv %t/cache %t/cache-explicit-a-keep
//
// RUN: diff %t/cache-explicit-no-a-prune/c.pcm %t/cache-explicit-a-prune/c.pcm
// RUN: not diff %t/cache-explicit-no-a-keep/c.pcm %t/cache-explicit-a-keep/c.pcm

// Test with implicit module map search.
//
// RUN: %clang_cc1 -working-directory %t @%t/implicit-search-args.rsp
// RUN: mv %t/cache %t/cache-implicit-no-a-prune
// RUN: %clang_cc1 -working-directory %t @%t/implicit-search-args.rsp -fno-modules-prune-non-affecting-module-map-files
// RUN: mv %t/cache %t/cache-implicit-no-a-keep
//
// FIXME: Instead of removing "a/module.modulemap" from the file system, we
// could drop the "-I a" search path argument in combination with the
// "-fmodules-skip-header-search-paths" flag. Unfortunately, that flag
// does not prevent serialization of the search path usage bit vector,
// making the files differ anyways.
// RUN: rm %t/a/module.modulemap
//
// RUN: %clang_cc1 -working-directory %t @%t/implicit-search-args.rsp
// RUN: mv %t/cache %t/cache-implicit-a-prune
// RUN: %clang_cc1 -working-directory %t @%t/implicit-search-args.rsp -fno-modules-prune-non-affecting-module-map-files
// RUN: mv %t/cache %t/cache-implicit-a-keep
//
// RUN: diff %t/cache-implicit-no-a-prune/c.pcm %t/cache-implicit-a-prune/c.pcm
// RUN: not diff %t/cache-implicit-no-a-keep/c.pcm %t/cache-implicit-a-keep/c.pcm
18 changes: 18 additions & 0 deletions clang/test/SemaCXX/cxx20-ctad-type-alias.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -289,3 +289,21 @@ using String = Array<char, N>;
// Verify no crash on constructing the aggregate deduction guides.
String s("hello");
} // namespace test21

// GH89013
namespace test22 {
class Base {};
template <typename T>
class Derived final : public Base {};

template <typename T, typename D>
requires __is_base_of(Base, D)
struct Foo {
explicit Foo(D) {}
};

template <typename U>
using AFoo = Foo<int, Derived<U>>;

AFoo a(Derived<int>{});
} // namespace test22
28 changes: 28 additions & 0 deletions clang/test/SemaTemplate/deduction-guide.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -260,3 +260,31 @@ AG ag = {1};
// CHECK: |-TemplateArgument type 'int'
// CHECK: | `-BuiltinType {{.*}} 'int'
// CHECK: `-ParmVarDecl {{.*}} 'int'

template <typename D>
requires (sizeof(D) == 4)
struct Foo {
Foo(D);
};

template <typename U>
using AFoo = Foo<G<U>>;
// Verify that the require-clause from the Foo deduction guide is transformed.
// The D occurrence should be rewritten to G<type-parameter-0-0>.
//
// CHECK-LABEL: Dumping <deduction guide for AFoo>
// CHECK: FunctionTemplateDecl {{.*}} implicit <deduction guide for AFoo>
// CHECK-NEXT: |-TemplateTypeParmDecl {{.*}} typename depth 0 index 0 U
// CHECK-NEXT: |-ParenExpr {{.*}} 'bool'
// CHECK-NEXT: | `-BinaryOperator {{.*}} 'bool' '=='
// CHECK-NEXT: | |-UnaryExprOrTypeTraitExpr {{.*}} 'unsigned long' sizeof 'G<type-parameter-0-0>'
// CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'unsigned long' <IntegralCast>
// CHECK-NEXT: | `-IntegerLiteral {{.*}} 'int' 4
// CHECK-NEXT: |-CXXDeductionGuideDecl {{.*}} implicit <deduction guide for AFoo> 'auto (G<type-parameter-0-0>) -> Foo<G<type-parameter-0-0>>'
// CHECK-NEXT: | `-ParmVarDecl {{.*}} 'G<type-parameter-0-0>'
// CHECK-NEXT: `-CXXDeductionGuideDecl {{.*}} implicit used <deduction guide for AFoo> 'auto (G<int>) -> Foo<G<int>>' implicit_instantiation
// CHECK-NEXT: |-TemplateArgument type 'int'
// CHECK-NEXT: | `-BuiltinType {{.*}} 'int'
// CHECK-NEXT: `-ParmVarDecl {{.*}} 'G<int>'

AFoo aa(G<int>{});
4 changes: 3 additions & 1 deletion flang/include/flang/Lower/Allocatable.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,14 @@ void genDeallocateStmt(AbstractConverter &converter,

void genDeallocateBox(AbstractConverter &converter,
const fir::MutableBoxValue &box, mlir::Location loc,
const Fortran::semantics::Symbol *sym = nullptr,
mlir::Value declaredTypeDesc = {});

/// Deallocate an allocatable if it is allocated at the end of its lifetime.
void genDeallocateIfAllocated(AbstractConverter &converter,
const fir::MutableBoxValue &box,
mlir::Location loc);
mlir::Location loc,
const Fortran::semantics::Symbol *sym = nullptr);

/// Create a MutableBoxValue for an allocatable or pointer entity.
/// If the variables is a local variable that is not a dummy, it will be
Expand Down
12 changes: 7 additions & 5 deletions flang/lib/Lower/Allocatable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -859,18 +859,20 @@ genDeallocate(fir::FirOpBuilder &builder,
void Fortran::lower::genDeallocateBox(
Fortran::lower::AbstractConverter &converter,
const fir::MutableBoxValue &box, mlir::Location loc,
mlir::Value declaredTypeDesc) {
const Fortran::semantics::Symbol *sym, mlir::Value declaredTypeDesc) {
const Fortran::lower::SomeExpr *statExpr = nullptr;
const Fortran::lower::SomeExpr *errMsgExpr = nullptr;
ErrorManager errorManager;
errorManager.init(converter, loc, statExpr, errMsgExpr);
fir::FirOpBuilder &builder = converter.getFirOpBuilder();
genDeallocate(builder, converter, loc, box, errorManager, declaredTypeDesc);
genDeallocate(builder, converter, loc, box, errorManager, declaredTypeDesc,
sym);
}

void Fortran::lower::genDeallocateIfAllocated(
Fortran::lower::AbstractConverter &converter,
const fir::MutableBoxValue &box, mlir::Location loc) {
const fir::MutableBoxValue &box, mlir::Location loc,
const Fortran::semantics::Symbol *sym) {
fir::FirOpBuilder &builder = converter.getFirOpBuilder();
mlir::Value isAllocated =
fir::factory::genIsAllocatedOrAssociatedTest(builder, loc, box);
Expand All @@ -880,9 +882,9 @@ void Fortran::lower::genDeallocateIfAllocated(
eleType.isa<fir::RecordType>() && box.isPolymorphic()) {
mlir::Value declaredTypeDesc = builder.create<fir::TypeDescOp>(
loc, mlir::TypeAttr::get(eleType));
genDeallocateBox(converter, box, loc, declaredTypeDesc);
genDeallocateBox(converter, box, loc, sym, declaredTypeDesc);
} else {
genDeallocateBox(converter, box, loc);
genDeallocateBox(converter, box, loc, sym);
}
})
.end();
Expand Down
5 changes: 3 additions & 2 deletions flang/lib/Lower/ConvertVariable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -916,13 +916,14 @@ static void instantiateLocal(Fortran::lower::AbstractConverter &converter,
break;
case VariableCleanUp::Deallocate:
auto *converterPtr = &converter;
converter.getFctCtx().attachCleanup([converterPtr, loc, exv]() {
auto *sym = &var.getSymbol();
converter.getFctCtx().attachCleanup([converterPtr, loc, exv, sym]() {
const fir::MutableBoxValue *mutableBox =
exv.getBoxOf<fir::MutableBoxValue>();
assert(mutableBox &&
"trying to deallocate entity not lowered as allocatable");
Fortran::lower::genDeallocateIfAllocated(*converterPtr, *mutableBox,
loc);
loc, sym);
});
}
}
Expand Down
4 changes: 2 additions & 2 deletions flang/lib/Lower/OpenMP/ReductionProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -220,12 +220,12 @@ mlir::Value ReductionProcessor::createScalarCombiner(
switch (redId) {
case ReductionIdentifier::MAX:
reductionOp =
getReductionOperation<mlir::arith::MaximumFOp, mlir::arith::MaxSIOp>(
getReductionOperation<mlir::arith::MaxNumFOp, mlir::arith::MaxSIOp>(
builder, type, loc, op1, op2);
break;
case ReductionIdentifier::MIN:
reductionOp =
getReductionOperation<mlir::arith::MinimumFOp, mlir::arith::MinSIOp>(
getReductionOperation<mlir::arith::MinNumFOp, mlir::arith::MinSIOp>(
builder, type, loc, op1, op2);
break;
case ReductionIdentifier::IOR:
Expand Down
14 changes: 14 additions & 0 deletions flang/lib/Semantics/check-allocate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,20 @@ bool AllocationCheckerHelper::RunChecks(SemanticsContext &context) {
return false;
}
}
if (allocateInfo_.gotPinned) {
std::optional<common::CUDADataAttr> cudaAttr{GetCUDADataAttr(ultimate_)};
if (!cudaAttr || *cudaAttr != common::CUDADataAttr::Pinned) {
context.Say(name_.source,
"Object in ALLOCATE must have PINNED attribute when PINNED option is specified"_err_en_US);
}
}
if (allocateInfo_.gotStream) {
std::optional<common::CUDADataAttr> cudaAttr{GetCUDADataAttr(ultimate_)};
if (!cudaAttr || *cudaAttr != common::CUDADataAttr::Device) {
context.Say(name_.source,
"Object in ALLOCATE must have DEVICE attribute when STREAM option is specified"_err_en_US);
}
}
return RunCoarrayRelatedChecks(context);
}

Expand Down
4 changes: 2 additions & 2 deletions flang/lib/Semantics/check-declarations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -956,9 +956,9 @@ void CheckHelper::CheckObjectEntity(
break;
case common::CUDADataAttr::Managed:
if (!IsAutomatic(symbol) && !IsAllocatable(symbol) &&
!details.isDummy()) {
!details.isDummy() && !evaluate::IsExplicitShape(symbol)) {
messages_.Say(
"Object '%s' with ATTRIBUTES(MANAGED) must also be allocatable, automatic, or a dummy argument"_err_en_US,
"Object '%s' with ATTRIBUTES(MANAGED) must also be allocatable, automatic, explicit shape, or a dummy argument"_err_en_US,
symbol.name());
}
break;
Expand Down
36 changes: 33 additions & 3 deletions flang/test/Lower/CUDA/cuda-allocatable.cuf
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,15 @@ end subroutine

! CHECK: %{{.*}} = fir.cuda_deallocate %[[BOX_DECL]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>> {cuda_attr = #fir.cuda<device>} -> i32

! CHECK: %[[BOX_LOAD:.*]] = fir.load %[[BOX_DECL]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
! CHECK: %[[ADDR:.*]] = fir.box_addr %[[BOX_LOAD]] : (!fir.box<!fir.heap<!fir.array<?xf32>>>) -> !fir.heap<!fir.array<?xf32>>
! CHECK: %[[ADDR_I64:.*]] = fir.convert %[[ADDR]] : (!fir.heap<!fir.array<?xf32>>) -> i64
! CHECK: %[[C0:.*]] = arith.constant 0 : i64
! CHECK: %[[NE_C0:.*]] = arith.cmpi ne, %[[ADDR_I64]], %[[C0]] : i64
! CHECK: fir.if %[[NE_C0]] {
! CHECK: %{{.*}} = fir.cuda_deallocate %[[BOX_DECL]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>> {cuda_attr = #fir.cuda<device>} -> i32
! CHECK: }

subroutine sub2()
real, allocatable, managed :: a(:)
integer :: istat
Expand All @@ -37,6 +46,10 @@ end subroutine
! CHECK: %[[STAT:.*]] = fir.cuda_deallocate %[[BOX_DECL]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>> {cuda_attr = #fir.cuda<managed>, hasStat} -> i32
! CHECK: fir.store %[[STAT]] to %[[ISTAT_DECL]]#1 : !fir.ref<i32>

! CHECK: fir.if %{{.*}} {
! CHECK: %{{.*}} = fir.cuda_deallocate %[[BOX_DECL]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>> {cuda_attr = #fir.cuda<managed>} -> i32
! CHECK: }

subroutine sub3()
integer, allocatable, pinned :: a(:,:)
logical :: plog
Expand All @@ -50,21 +63,27 @@ end subroutine
! CHECK: %[[PLOG_DECL:.*]]:2 = hlfir.declare %5 {uniq_name = "_QFsub3Eplog"} : (!fir.ref<!fir.logical<4>>) -> (!fir.ref<!fir.logical<4>>, !fir.ref<!fir.logical<4>>)
! CHECK-2: fir.call @_FortranAAllocatableSetBounds
! CHECK: %{{.*}} = fir.cuda_allocate %[[BOX_DECL]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xi32>>>> pinned(%[[PLOG_DECL]]#1 : !fir.ref<!fir.logical<4>>) {cuda_attr = #fir.cuda<pinned>} -> i32
! CHECK: fir.if %{{.*}} {
! CHECK: %{{.*}} = fir.cuda_deallocate %[[BOX_DECL]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xi32>>>> {cuda_attr = #fir.cuda<pinned>} -> i32
! CHECK: }

subroutine sub4()
real, allocatable, unified :: a(:)
real, allocatable, device :: a(:)
integer :: istream
allocate(a(10), stream=istream)
end subroutine

! CHECK-LABEL: func.func @_QPsub4()
! CHECK: %[[BOX:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?xf32>>> {bindc_name = "a", uniq_name = "_QFsub4Ea"}
! CHECK: %[[BOX_DECL:.*]]:2 = hlfir.declare %0 {cuda_attr = #fir.cuda<unified>, fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFsub4Ea"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>)
! CHECK: %[[BOX_DECL:.*]]:2 = hlfir.declare %0 {cuda_attr = #fir.cuda<device>, fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFsub4Ea"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>)
! CHECK: %[[ISTREAM:.*]] = fir.alloca i32 {bindc_name = "istream", uniq_name = "_QFsub4Eistream"}
! CHECK: %[[ISTREAM_DECL:.*]]:2 = hlfir.declare %[[ISTREAM]] {uniq_name = "_QFsub4Eistream"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
! CHECK: fir.call @_FortranAAllocatableSetBounds
! CHECK: %[[STREAM:.*]] = fir.load %[[ISTREAM_DECL]]#0 : !fir.ref<i32>
! CHECK: %{{.*}} = fir.cuda_allocate %[[BOX_DECL]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>> stream(%[[STREAM]] : i32) {cuda_attr = #fir.cuda<unified>} -> i32
! CHECK: %{{.*}} = fir.cuda_allocate %[[BOX_DECL]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>> stream(%[[STREAM]] : i32) {cuda_attr = #fir.cuda<device>} -> i32
! CHECK: fir.if %{{.*}} {
! CHECK: %{{.*}} = fir.cuda_deallocate %[[BOX_DECL]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>> {cuda_attr = #fir.cuda<device>} -> i32
! CHECK: }

subroutine sub5()
real, allocatable, device :: a(:)
Expand All @@ -80,6 +99,11 @@ end subroutine
! CHECK: %[[LOAD_B:.*]] = fir.load %[[BOX_B_DECL]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
! CHECK: fir.call @_FortranAAllocatableSetBounds
! CHECK: %{{.*}} = fir.cuda_allocate %[[BOX_A_DECL]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>> source(%[[LOAD_B]] : !fir.box<!fir.heap<!fir.array<?xf32>>>) {cuda_attr = #fir.cuda<device>} -> i32
! CHECK: fir.if
! CHECK: fir.freemem
! CHECK: fir.if %{{.*}} {
! CHECK: %{{.*}} = fir.cuda_deallocate %[[BOX_A_DECL]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>> {cuda_attr = #fir.cuda<device>} -> i32
! CHECK: }

subroutine sub6()
real, allocatable, device :: a(:)
Expand All @@ -95,6 +119,9 @@ end subroutine
! CHECK: %[[LOAD_B:.*]] = fir.load %[[BOX_B_DECL]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
! CHECK: fir.call @_FortranAAllocatableApplyMold
! CHECK: %{{.*}} = fir.cuda_allocate %[[BOX_A_DECL]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>> {cuda_attr = #fir.cuda<device>} -> i32
! CHECK: fir.if %{{.*}} {
! CHECK: %{{.*}} = fir.cuda_deallocate %[[BOX_A_DECL]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>> {cuda_attr = #fir.cuda<device>} -> i32
! CHECK: }

subroutine sub7()
real, allocatable, device :: a(:)
Expand All @@ -120,3 +147,6 @@ end subroutine
! CHECK: %[[ERR_BOX:.*]] = fir.embox %[[ERR_DECL]]#1 : (!fir.ref<!fir.char<1,50>>) -> !fir.box<!fir.char<1,50>>
! CHECK: %[[STAT:.*]] = fir.cuda_deallocate %[[BOX_DECL]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>> errmsg(%15 : !fir.box<!fir.char<1,50>>) {cuda_attr = #fir.cuda<device>, hasStat} -> i32
! CHECK: fir.store %[[STAT]] to %[[ISTAT_DECL]]#1 : !fir.ref<i32>
! CHECK: fir.if %{{.*}} {
! CHECK: %{{.*}} = fir.cuda_deallocate %[[BOX_DECL]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>> {cuda_attr = #fir.cuda<device>} -> i32
! CHECK: }
2 changes: 1 addition & 1 deletion flang/test/Lower/OpenMP/FIR/wsloop-reduction-max-byref.f90
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
!CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref<f32>, %[[ARG1:.*]]: !fir.ref<f32>):
!CHECK: %[[LD0:.*]] = fir.load %[[ARG0]] : !fir.ref<f32>
!CHECK: %[[LD1:.*]] = fir.load %[[ARG1]] : !fir.ref<f32>
!CHECK: %[[RES:.*]] = arith.maximumf %[[LD0]], %[[LD1]] {{.*}}: f32
!CHECK: %[[RES:.*]] = arith.maxnumf %[[LD0]], %[[LD1]] {{.*}}: f32
!CHECK: fir.store %[[RES]] to %[[ARG0]] : !fir.ref<f32>
!CHECK: omp.yield(%[[ARG0]] : !fir.ref<f32>)

Expand Down
2 changes: 1 addition & 1 deletion flang/test/Lower/OpenMP/FIR/wsloop-reduction-max.f90
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
!CHECK: omp.yield(%[[MINIMUM_VAL_F]] : f32)
!CHECK: combiner
!CHECK: ^bb0(%[[ARG0_F:.*]]: f32, %[[ARG1_F:.*]]: f32):
!CHECK: %[[COMB_VAL_F:.*]] = arith.maximumf %[[ARG0_F]], %[[ARG1_F]] {{.*}}: f32
!CHECK: %[[COMB_VAL_F:.*]] = arith.maxnumf %[[ARG0_F]], %[[ARG1_F]] {{.*}}: f32
!CHECK: omp.yield(%[[COMB_VAL_F]] : f32)

!CHECK: omp.declare_reduction @[[MAX_DECLARE_I:.*]] : i32 init {
Expand Down
2 changes: 1 addition & 1 deletion flang/test/Lower/OpenMP/FIR/wsloop-reduction-min-byref.f90
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
!CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref<f32>, %[[ARG1:.*]]: !fir.ref<f32>):
!CHECK: %[[LD0:.*]] = fir.load %[[ARG0]] : !fir.ref<f32>
!CHECK: %[[LD1:.*]] = fir.load %[[ARG1]] : !fir.ref<f32>
!CHECK: %[[RES:.*]] = arith.minimumf %[[LD0]], %[[LD1]] {{.*}}: f32
!CHECK: %[[RES:.*]] = arith.minnumf %[[LD0]], %[[LD1]] {{.*}}: f32
!CHECK: fir.store %[[RES]] to %[[ARG0]] : !fir.ref<f32>
!CHECK: omp.yield(%[[ARG0]] : !fir.ref<f32>)

Expand Down
2 changes: 1 addition & 1 deletion flang/test/Lower/OpenMP/FIR/wsloop-reduction-min.f90
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
!CHECK: omp.yield(%[[MAXIMUM_VAL_F]] : f32)
!CHECK: combiner
!CHECK: ^bb0(%[[ARG0_F:.*]]: f32, %[[ARG1_F:.*]]: f32):
!CHECK: %[[COMB_VAL_F:.*]] = arith.minimumf %[[ARG0_F]], %[[ARG1_F]] {{.*}}: f32
!CHECK: %[[COMB_VAL_F:.*]] = arith.minnumf %[[ARG0_F]], %[[ARG1_F]] {{.*}}: f32
!CHECK: omp.yield(%[[COMB_VAL_F]] : f32)

!CHECK: omp.declare_reduction @[[MIN_DECLARE_I:.*]] : i32 init {
Expand Down
2 changes: 1 addition & 1 deletion flang/test/Lower/OpenMP/wsloop-reduction-max-byref.f90
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
!CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref<f32>, %[[ARG1:.*]]: !fir.ref<f32>):
!CHECK: %[[LD0:.*]] = fir.load %[[ARG0]] : !fir.ref<f32>
!CHECK: %[[LD1:.*]] = fir.load %[[ARG1]] : !fir.ref<f32>
!CHECK: %[[RES:.*]] = arith.maximumf %[[LD0]], %[[LD1]] {{.*}}: f32
!CHECK: %[[RES:.*]] = arith.maxnumf %[[LD0]], %[[LD1]] {{.*}}: f32
!CHECK: fir.store %[[RES]] to %[[ARG0]] : !fir.ref<f32>
!CHECK: omp.yield(%[[ARG0]] : !fir.ref<f32>)

Expand Down
2 changes: 1 addition & 1 deletion flang/test/Lower/OpenMP/wsloop-reduction-max.f90
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

! CHECK-LABEL: } combiner {
! CHECK: ^bb0(%[[VAL_0:.*]]: f32, %[[VAL_1:.*]]: f32):
! CHECK: %[[VAL_2:.*]] = arith.maximumf %[[VAL_0]], %[[VAL_1]] fastmath<contract> : f32
! CHECK: %[[VAL_2:.*]] = arith.maxnumf %[[VAL_0]], %[[VAL_1]] fastmath<contract> : f32
! CHECK: omp.yield(%[[VAL_2]] : f32)
! CHECK: }

Expand Down
2 changes: 1 addition & 1 deletion flang/test/Lower/OpenMP/wsloop-reduction-min-byref.f90
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
!CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref<f32>, %[[ARG1:.*]]: !fir.ref<f32>):
!CHECK: %[[LD0:.*]] = fir.load %[[ARG0]] : !fir.ref<f32>
!CHECK: %[[LD1:.*]] = fir.load %[[ARG1]] : !fir.ref<f32>
!CHECK: %[[RES:.*]] = arith.minimumf %[[LD0]], %[[LD1]] {{.*}}: f32
!CHECK: %[[RES:.*]] = arith.minnumf %[[LD0]], %[[LD1]] {{.*}}: f32
!CHECK: fir.store %[[RES]] to %[[ARG0]] : !fir.ref<f32>
!CHECK: omp.yield(%[[ARG0]] : !fir.ref<f32>)

Expand Down
2 changes: 1 addition & 1 deletion flang/test/Lower/OpenMP/wsloop-reduction-min.f90
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

! CHECK-LABEL: } combiner {
! CHECK: ^bb0(%[[VAL_0:.*]]: f32, %[[VAL_1:.*]]: f32):
! CHECK: %[[VAL_2:.*]] = arith.minimumf %[[VAL_0]], %[[VAL_1]] fastmath<contract> : f32
! CHECK: %[[VAL_2:.*]] = arith.minnumf %[[VAL_0]], %[[VAL_1]] fastmath<contract> : f32
! CHECK: omp.yield(%[[VAL_2]] : f32)
! CHECK: }

Expand Down
2 changes: 1 addition & 1 deletion flang/test/Parser/cuf-sanity-common
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,6 @@ module m
call globalsub<<<1, 2>>>
call globalsub<<<1, 2, 3>>>
call globalsub<<<1, 2, 3, 4>>>
allocate(pa(32), stream = 1, pinned = isPinned)
allocate(pa(32), pinned = isPinned)
end subroutine
end module
2 changes: 0 additions & 2 deletions flang/test/Parser/cuf-sanity-tree.CUF
Original file line number Diff line number Diff line change
Expand Up @@ -199,8 +199,6 @@ include "cuf-sanity-common"
!CHECK: | | | | | | AllocateShapeSpec
!CHECK: | | | | | | | Scalar -> Integer -> Expr = '32_4'
!CHECK: | | | | | | | | LiteralConstant -> IntLiteralConstant = '32'
!CHECK: | | | | | AllocOpt -> Stream -> Scalar -> Integer -> Expr = '1_4'
!CHECK: | | | | | | LiteralConstant -> IntLiteralConstant = '1'
!CHECK: | | | | | AllocOpt -> Pinned -> Scalar -> Logical -> Variable = 'ispinned'
!CHECK: | | | | | | Designator -> DataRef -> Name = 'ispinned'
!CHECK: | | | EndSubroutineStmt ->
Expand Down
2 changes: 1 addition & 1 deletion flang/test/Parser/cuf-sanity-unparse.CUF
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,6 @@ include "cuf-sanity-common"
!CHECK: CALL globalsub<<<1_4,2_4>>>()
!CHECK: CALL globalsub<<<1_4,2_4,3_4>>>()
!CHECK: CALL globalsub<<<1_4,2_4,3_4,4_4>>>()
!CHECK: ALLOCATE(pa(32_4), STREAM=1_4, PINNED=ispinned)
!CHECK: ALLOCATE(pa(32_4), PINNED=ispinned)
!CHECK: END SUBROUTINE
!CHECK: END MODULE
11 changes: 4 additions & 7 deletions flang/test/Semantics/cuf03.cuf
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,11 @@ module m
real, shared, target :: mst
!ERROR: Object 'msa' with ATTRIBUTES(SHARED) must be declared in a device subprogram
real, shared :: msa(*)
!ERROR: Object 'mm' with ATTRIBUTES(MANAGED) must also be allocatable, automatic, or a dummy argument
real, managed :: mm
!ERROR: Object 'mmi' with ATTRIBUTES(MANAGED) must also be allocatable, automatic, or a dummy argument
real, managed :: mmi = 1.
real, managed :: mm ! ok
real, managed :: mmi = 1. ! ok
real, managed, allocatable :: mml ! ok
!ERROR: Object 'mmp' with ATTRIBUTES(MANAGED) must also be allocatable, automatic, or a dummy argument
real, managed, pointer :: mmp ! ok
!ERROR: Object 'mmt' with ATTRIBUTES(MANAGED) must also be allocatable, automatic, or a dummy argument
!ERROR: Object 'mmp' with ATTRIBUTES(MANAGED) must also be allocatable, automatic, explicit shape, or a dummy argument
real, managed, pointer :: mmp(:)
real, managed, target :: mmt
!WARNING: Object 'mp' with ATTRIBUTES(PINNED) should also be allocatable
real, pinned :: mp
Expand Down
16 changes: 16 additions & 0 deletions flang/test/Semantics/cuf07.cuf
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,20 @@ module m
!BECAUSE: 'ma' is a host-associated allocatable and is not definable in a device subprogram
deallocate(ma)
end subroutine

subroutine hostsub()
integer, allocatable, device :: ia(:)
logical :: plog

!ERROR: Object in ALLOCATE must have PINNED attribute when PINNED option is specified
allocate(ia(100), pinned = plog)
end subroutine

subroutine host2()
integer, allocatable, pinned :: ia(:)
integer :: istream

!ERROR: Object in ALLOCATE must have DEVICE attribute when STREAM option is specified
allocate(ia(100), stream = istream)
end subroutine
end module
4 changes: 3 additions & 1 deletion lldb/source/Expression/IRExecutionUnit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,9 @@ void IRExecutionUnit::GetRunnableInfo(Status &error, lldb::addr_t &func_addr,
}

m_failed_lookups.clear();

ss.PutCString(
"\nHint: The expression tried to call a function that is not present "
"in the target, perhaps because it was optimized out by the compiler.");
error.SetErrorString(ss.GetString());

return;
Expand Down
2 changes: 1 addition & 1 deletion lldb/test/API/lang/cpp/constructors/TestCppConstructors.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def test_constructors(self):
self.expect(
"expr ClassWithDeletedDefaultCtor().value",
error=True,
substrs=["Couldn't look up symbols:"],
substrs=["Couldn't look up symbols:", "function missing"],
)

@skipIfWindows # Can't find operator new.
Expand Down
2 changes: 1 addition & 1 deletion lldb/unittests/Host/FileSystemTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ class DummyFileSystem : public vfs::FileSystem {
std::map<std::string, vfs::Status>::iterator I;
std::string Path;
bool isInPath(StringRef S) {
if (Path.size() < S.size() && S.find(Path) == 0) {
if (Path.size() < S.size() && S.starts_with(Path)) {
auto LastSep = S.find_last_of('/');
if (LastSep == Path.size() || LastSep == Path.size() - 1)
return true;
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3359,7 +3359,7 @@ SDValue DAGCombiner::visitUADDO_CARRY(SDNode *N) {
}

/**
* If we are facing some sort of diamond carry propapagtion pattern try to
* If we are facing some sort of diamond carry propagation pattern try to
* break it up to generate something like:
* (uaddo_carry X, 0, (uaddo_carry A, B, Z):Carry)
*
Expand Down Expand Up @@ -3400,7 +3400,7 @@ static SDValue combineUADDO_CARRYDiamond(DAGCombiner &Combiner,
Z = Carry0.getOperand(2);
} else if (Carry0.getOpcode() == ISD::UADDO &&
isOneConstant(Carry0.getOperand(1))) {
EVT VT = Combiner.getSetCCResultType(Carry0.getValueType());
EVT VT = Carry0->getValueType(1);
Z = DAG.getConstant(1, SDLoc(Carry0.getOperand(1)), VT);
} else {
// We couldn't find a suitable Z.
Expand Down
20 changes: 1 addition & 19 deletions llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -949,7 +949,7 @@ SDValue DAGTypeLegalizer::PromoteIntRes_Overflow(SDNode *N) {
unsigned NumOps = N->getNumOperands();
assert(NumOps <= 3 && "Too many operands");
if (NumOps == 3)
Ops[2] = N->getOperand(2);
Ops[2] = PromoteTargetBoolean(N->getOperand(2), VT);

SDLoc dl(N);
SDValue Res = DAG.getNode(N->getOpcode(), dl, DAG.getVTList(VT, SVT),
Expand Down Expand Up @@ -1867,11 +1867,6 @@ bool DAGTypeLegalizer::PromoteIntegerOperand(SDNode *N, unsigned OpNo) {
case ISD::FSHL:
case ISD::FSHR: Res = PromoteIntOp_FunnelShift(N); break;

case ISD::SADDO_CARRY:
case ISD::SSUBO_CARRY:
case ISD::UADDO_CARRY:
case ISD::USUBO_CARRY: Res = PromoteIntOp_ADDSUBO_CARRY(N, OpNo); break;

case ISD::FRAMEADDR:
case ISD::RETURNADDR: Res = PromoteIntOp_FRAMERETURNADDR(N); break;

Expand Down Expand Up @@ -2373,19 +2368,6 @@ SDValue DAGTypeLegalizer::PromoteIntOp_VP_ZERO_EXTEND(SDNode *N) {
N->getOperand(1), N->getOperand(2));
}

SDValue DAGTypeLegalizer::PromoteIntOp_ADDSUBO_CARRY(SDNode *N, unsigned OpNo) {
assert(OpNo == 2 && "Don't know how to promote this operand!");

SDValue LHS = N->getOperand(0);
SDValue RHS = N->getOperand(1);
SDValue Carry = N->getOperand(2);
SDLoc DL(N);

Carry = PromoteTargetBoolean(Carry, LHS.getValueType());

return SDValue(DAG.UpdateNodeOperands(N, LHS, RHS, Carry), 0);
}

SDValue DAGTypeLegalizer::PromoteIntOp_FIX(SDNode *N) {
SDValue Op2 = ZExtPromotedInteger(N->getOperand(2));
return SDValue(
Expand Down
1 change: 0 additions & 1 deletion llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,6 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
SDValue PromoteIntOp_MLOAD(MaskedLoadSDNode *N, unsigned OpNo);
SDValue PromoteIntOp_MSCATTER(MaskedScatterSDNode *N, unsigned OpNo);
SDValue PromoteIntOp_MGATHER(MaskedGatherSDNode *N, unsigned OpNo);
SDValue PromoteIntOp_ADDSUBO_CARRY(SDNode *N, unsigned OpNo);
SDValue PromoteIntOp_FRAMERETURNADDR(SDNode *N);
SDValue PromoteIntOp_FIX(SDNode *N);
SDValue PromoteIntOp_ExpOp(SDNode *N);
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9924,7 +9924,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, SDVTList VTList,
assert(VTList.VTs[0].isInteger() && VTList.VTs[1].isInteger() &&
Ops[0].getValueType() == Ops[1].getValueType() &&
Ops[0].getValueType() == VTList.VTs[0] &&
Ops[2].getValueType().isInteger() &&
Ops[2].getValueType() == VTList.VTs[1] &&
"Binary operator types must match!");
break;
case ISD::SMUL_LOHI:
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ class RISCVAsmParser : public MCTargetAsmParser {

SMLoc getLoc() const { return getParser().getTok().getLoc(); }
bool isRV64() const { return getSTI().hasFeature(RISCV::Feature64Bit); }
bool isRVE() const { return getSTI().hasFeature(RISCV::FeatureRVE); }
bool isRVE() const { return getSTI().hasFeature(RISCV::FeatureStdExtE); }

RISCVTargetStreamer &getTargetStreamer() {
assert(getParser().getStreamer().getTargetStreamer() &&
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVDisassembler() {
static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, uint32_t RegNo,
uint64_t Address,
const MCDisassembler *Decoder) {
bool IsRVE = Decoder->getSubtargetInfo().hasFeature(RISCV::FeatureRVE);
bool IsRVE = Decoder->getSubtargetInfo().hasFeature(RISCV::FeatureStdExtE);

if (RegNo >= 32 || (IsRVE && RegNo >= 16))
return MCDisassembler::Fail;
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ ABI computeTargetABI(const Triple &TT, const FeatureBitset &FeatureBits,
StringRef ABIName) {
auto TargetABI = getTargetABI(ABIName);
bool IsRV64 = TT.isArch64Bit();
bool IsRVE = FeatureBits[RISCV::FeatureRVE];
bool IsRVE = FeatureBits[RISCV::FeatureStdExtE];

if (!ABIName.empty() && TargetABI == ABI_Unknown) {
errs()
Expand Down
8 changes: 4 additions & 4 deletions llvm/lib/Target/RISCV/RISCVFeatures.td
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ def FeatureStdExtI
: SubtargetFeature<"i", "HasStdExtI", "true",
"'I' (Base Integer Instruction Set)">;

def FeatureStdExtE
: SubtargetFeature<"e", "HasStdExtE", "true",
"Implements RV{32,64}E (provides 16 rather than 32 GPRs)">;

def FeatureStdExtZic64b
: SubtargetFeature<"zic64b", "HasStdExtZic64b", "true",
"'Zic64b' (Cache Block Size Is 64 Bytes)">;
Expand Down Expand Up @@ -1162,10 +1166,6 @@ def IsRV32 : Predicate<"!Subtarget->is64Bit()">,
defvar RV32 = DefaultMode;
def RV64 : HwMode<"+64bit", [IsRV64]>;

def FeatureRVE
: SubtargetFeature<"e", "IsRVE", "true",
"Implements RV{32,64}E (provides 16 rather than 32 GPRs)">;

def FeatureRelax
: SubtargetFeature<"relax", "EnableLinkerRelax", "true",
"Enable Linker relaxation.">;
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/Target/RISCV/RISCVISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18951,7 +18951,7 @@ SDValue RISCVTargetLowering::LowerFormalArguments(
case CallingConv::RISCV_VectorCall:
break;
case CallingConv::GHC:
if (Subtarget.isRVE())
if (Subtarget.hasStdExtE())
report_fatal_error("GHC calling convention is not supported on RVE!");
if (!Subtarget.hasStdExtFOrZfinx() || !Subtarget.hasStdExtDOrZdinx())
report_fatal_error("GHC calling convention requires the (Zfinx/F) and "
Expand Down Expand Up @@ -19189,7 +19189,7 @@ SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI,
CCState ArgCCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext());

if (CallConv == CallingConv::GHC) {
if (Subtarget.isRVE())
if (Subtarget.hasStdExtE())
report_fatal_error("GHC calling convention is not supported on RVE!");
ArgCCInfo.AnalyzeCallOperands(Outs, RISCV::CC_RISCV_GHC);
} else
Expand Down
12 changes: 6 additions & 6 deletions llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,10 @@ RISCVRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
if (Subtarget.hasStdExtD())
return CSR_XLEN_F64_Interrupt_SaveList;
if (Subtarget.hasStdExtF())
return Subtarget.isRVE() ? CSR_XLEN_F32_Interrupt_RVE_SaveList
: CSR_XLEN_F32_Interrupt_SaveList;
return Subtarget.isRVE() ? CSR_Interrupt_RVE_SaveList
: CSR_Interrupt_SaveList;
return Subtarget.hasStdExtE() ? CSR_XLEN_F32_Interrupt_RVE_SaveList
: CSR_XLEN_F32_Interrupt_SaveList;
return Subtarget.hasStdExtE() ? CSR_Interrupt_RVE_SaveList
: CSR_Interrupt_SaveList;
}

bool HasVectorCSR =
Expand Down Expand Up @@ -126,7 +126,7 @@ BitVector RISCVRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
markSuperRegs(Reserved, RISCV::DUMMY_REG_PAIR_WITH_X0);

// There are only 16 GPRs for RVE.
if (Subtarget.isRVE())
if (Subtarget.hasStdExtE())
for (MCPhysReg Reg = RISCV::X16; Reg <= RISCV::X31; Reg++)
markSuperRegs(Reserved, Reg);

Expand All @@ -145,7 +145,7 @@ BitVector RISCVRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
markSuperRegs(Reserved, RISCV::VCIX_STATE);

if (MF.getFunction().getCallingConv() == CallingConv::GRAAL) {
if (Subtarget.isRVE())
if (Subtarget.hasStdExtE())
report_fatal_error("Graal reserved registers do not exist in RVE");
markSuperRegs(Reserved, RISCV::X23);
markSuperRegs(Reserved, RISCV::X27);
Expand Down
27 changes: 24 additions & 3 deletions llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13139,9 +13139,30 @@ Value *BoUpSLP::vectorizeTree(
assert(Vec->getType()->isIntOrIntVectorTy() &&
PrevVec->getType()->isIntOrIntVectorTy() &&
"Expected integer vector types only.");
assert(MinBWs.contains(TE->UserTreeIndices.front().UserTE) &&
"Expected user in MinBWs.");
bool IsSigned = MinBWs.lookup(TE->UserTreeIndices.front().UserTE).second;
std::optional<std::pair<unsigned long, bool>> Res;
if (const TreeEntry *BaseTE = getTreeEntry(TE->Scalars.front())) {
SmallVector<const TreeEntry *> BaseTEs;
if (BaseTE->isSame(TE->Scalars))
BaseTEs.push_back(BaseTE);
auto It = MultiNodeScalars.find(TE->Scalars.front());
if (It != MultiNodeScalars.end()) {
for (const TreeEntry *MNTE : It->getSecond())
if (MNTE->isSame(TE->Scalars))
BaseTEs.push_back(MNTE);
}
const auto *BaseIt = find_if(BaseTEs, [&](const TreeEntry *BaseTE) {
return MinBWs.contains(BaseTE);
});
if (BaseIt != BaseTEs.end())
Res = MinBWs.lookup(*BaseIt);
}
if (!Res) {
assert(MinBWs.contains(TE->UserTreeIndices.front().UserTE) &&
"Expected user in MinBWs.");
Res = MinBWs.lookup(TE->UserTreeIndices.front().UserTE);
}
assert(Res && "Expected user node or perfect diamond match in MinBWs.");
bool IsSigned = Res->second;
Vec = Builder.CreateIntCast(Vec, PrevVec->getType(), IsSigned);
}
PrevVec->replaceAllUsesWith(Vec);
Expand Down
84 changes: 84 additions & 0 deletions llvm/test/Transforms/SLPVectorizer/X86/gather-node-same-reduced.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
; RUN: opt -S --passes=slp-vectorizer -mtriple=x86_64-unknown-linux < %s | FileCheck %s

define i64 @test(ptr %p) {
; CHECK-LABEL: define i64 @test(
; CHECK-SAME: ptr [[P:%.*]]) {
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[P]], i64 12
; CHECK-NEXT: [[TMP2:%.*]] = xor <4 x i32> zeroinitializer, zeroinitializer
; CHECK-NEXT: [[TMP3:%.*]] = xor <4 x i32> [[TMP2]], zeroinitializer
; CHECK-NEXT: [[TMP4:%.*]] = xor <4 x i32> [[TMP3]], zeroinitializer
; CHECK-NEXT: [[TMP5:%.*]] = xor <4 x i32> [[TMP4]], zeroinitializer
; CHECK-NEXT: [[TMP6:%.*]] = xor <4 x i32> [[TMP5]], zeroinitializer
; CHECK-NEXT: [[TMP7:%.*]] = xor <4 x i32> [[TMP6]], zeroinitializer
; CHECK-NEXT: [[TMP8:%.*]] = xor <4 x i32> [[TMP7]], zeroinitializer
; CHECK-NEXT: [[TMP9:%.*]] = xor <4 x i32> [[TMP8]], zeroinitializer
; CHECK-NEXT: [[TMP10:%.*]] = xor <4 x i32> [[TMP9]], zeroinitializer
; CHECK-NEXT: [[TMP11:%.*]] = xor <4 x i32> [[TMP10]], zeroinitializer
; CHECK-NEXT: [[TMP12:%.*]] = trunc <4 x i32> [[TMP11]] to <4 x i8>
; CHECK-NEXT: store <4 x i8> [[TMP12]], ptr [[TMP1]], align 1
; CHECK-NEXT: ret i64 0
;
%1 = getelementptr i8, ptr %p, i64 13
%2 = getelementptr i8, ptr %p, i64 14
%3 = getelementptr i8, ptr %p, i64 15
%4 = getelementptr i8, ptr %p, i64 12
%5 = zext i8 0 to i32
%6 = and i32 %5, 0
%.not866 = icmp eq i32 %6, 0
%7 = select i1 %.not866, i32 0, i32 0
%8 = xor i32 0, %7
%9 = zext i8 0 to i32
%10 = and i32 %9, 0
%.not871 = icmp eq i32 %10, 0
%11 = select i1 %.not871, i32 0, i32 0
%12 = xor i32 0, %11
%13 = xor i32 %9, 0
%14 = xor i32 %13, 0
%15 = xor i32 %14, 0
%16 = xor i32 %15, 0
%17 = xor i32 %16, 0
%18 = xor i32 %17, %12
%19 = xor i32 %18, 0
%20 = xor i32 %19, 0
%21 = xor i32 %20, 0
%22 = xor i32 %21, 0
%23 = trunc i32 %22 to i8
store i8 %23, ptr %4, align 1
%24 = xor i32 %9, 0
%25 = xor i32 %24, 0
%26 = xor i32 %25, 0
%27 = xor i32 %26, 0
%28 = xor i32 %27, 0
%29 = xor i32 %28, %8
%30 = xor i32 %29, 0
%31 = xor i32 %30, 0
%32 = xor i32 %31, 0
%33 = xor i32 %32, 0
%34 = trunc i32 %33 to i8
store i8 %34, ptr %1, align 1
%35 = xor i32 0, %5
%36 = xor i32 %35, 0
%37 = xor i32 %36, 0
%38 = xor i32 %37, 0
%39 = xor i32 %38, 0
%40 = xor i32 %39, %8
%41 = xor i32 %40, 0
%42 = xor i32 %41, 0
%43 = xor i32 %42, 0
%44 = xor i32 %43, 0
%45 = trunc i32 %44 to i8
store i8 %45, ptr %2, align 1
%46 = xor i32 %35, 0
%47 = xor i32 %46, 0
%48 = xor i32 %47, 0
%49 = xor i32 %48, 0
%50 = xor i32 %49, %8
%51 = xor i32 %50, 0
%52 = xor i32 %51, 0
%53 = xor i32 %52, 0
%54 = xor i32 %53, 0
%55 = trunc i32 %54 to i8
store i8 %55, ptr %3, align 1
ret i64 0
}
2 changes: 1 addition & 1 deletion llvm/unittests/Support/VirtualFileSystemTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ class DummyFileSystem : public vfs::FileSystem {
std::map<std::string, vfs::Status>::iterator I;
std::string Path;
bool isInPath(StringRef S) {
if (Path.size() < S.size() && S.find(Path) == 0) {
if (Path.size() < S.size() && S.starts_with(Path)) {
auto LastSep = S.find_last_of('/');
if (LastSep == Path.size() || LastSep == Path.size() - 1)
return true;
Expand Down
9 changes: 3 additions & 6 deletions llvm/utils/TableGen/X86FoldTablesEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
#include "Common/CodeGenTarget.h"
#include "X86RecognizableInstr.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/X86FoldTablesUtils.h"
#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/TableGenBackend.h"
Expand Down Expand Up @@ -95,7 +94,7 @@ class X86FoldTablesEmitter {
const CodeGenInstruction *MemInst)
: RegInst(RegInst), MemInst(MemInst) {}

void print(formatted_raw_ostream &OS) const {
void print(raw_ostream &OS) const {
OS.indent(2);
OS << "{X86::" << RegInst->TheDef->getName() << ", ";
OS << "X86::" << MemInst->TheDef->getName() << ", ";
Expand Down Expand Up @@ -222,7 +221,7 @@ class X86FoldTablesEmitter {
// Print the given table as a static const C++ array of type
// X86FoldTableEntry.
void printTable(const FoldTable &Table, StringRef TableName,
formatted_raw_ostream &OS) {
raw_ostream &OS) {
OS << "static const X86FoldTableEntry " << TableName << "[] = {\n";

for (auto &E : Table)
Expand Down Expand Up @@ -619,9 +618,7 @@ void X86FoldTablesEmitter::updateTables(const CodeGenInstruction *RegInst,
}
}

void X86FoldTablesEmitter::run(raw_ostream &O) {
formatted_raw_ostream OS(O);

void X86FoldTablesEmitter::run(raw_ostream &OS) {
// Holds all memory instructions
std::vector<const CodeGenInstruction *> MemInsts;
// Holds all register instructions - divided according to opcode.
Expand Down
3 changes: 2 additions & 1 deletion mlir/python/mlir/dialects/memref.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@
from ._memref_ops_gen import *
from ._ods_common import _dispatch_mixed_values, MixedValues
from .arith import ConstantOp, _is_integer_like_type
from ..ir import Value, MemRefType, StridedLayoutAttr, ShapedType
from ..ir import Value, MemRefType, StridedLayoutAttr, ShapedType, Operation


def _is_constant_int_like(i):
return (
isinstance(i, Value)
and isinstance(i.owner, Operation)
and isinstance(i.owner.opview, ConstantOp)
and _is_integer_like_type(i.type)
)
Expand Down