From c4c54af569f7c17bc89ae73c3e5c5c4be0a586b9 Mon Sep 17 00:00:00 2001 From: Farzon Lotfi <1802579+farzonl@users.noreply.github.com> Date: Mon, 22 Apr 2024 12:40:21 -0400 Subject: [PATCH 001/732] [SPIRV][HLSL] map lerp to Fmix (#88976) - `clang/lib/CodeGen/CGBuiltin.cpp` - switch to using `getLerpIntrinsic()` to abstract backend intrinsic - `clang/lib/CodeGen/CGHLSLRuntime.h` - add `getLerpIntrinsic()` - `llvm/include/llvm/IR/IntrinsicsSPIRV.td` - add SPIRV intrinsic for lerp - `llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp` - add mapping of HLSL's lerp to GLSL's Fmix. resolves #88940 --- clang/lib/CodeGen/CGBuiltin.cpp | 4 +- clang/lib/CodeGen/CGHLSLRuntime.h | 1 + .../CodeGenHLSL/builtins/lerp-builtin.hlsl | 8 +- clang/test/CodeGenHLSL/builtins/lerp.hlsl | 96 ++++++++++++------- llvm/include/llvm/IR/IntrinsicsSPIRV.td | 2 + .../Target/SPIRV/SPIRVInstructionSelector.cpp | 26 +++++ .../test/CodeGen/SPIRV/hlsl-intrinsics/all.ll | 76 +++++++-------- .../test/CodeGen/SPIRV/hlsl-intrinsics/any.ll | 76 +++++++-------- .../CodeGen/SPIRV/hlsl-intrinsics/lerp.ll | 56 +++++++++++ .../test/CodeGen/SPIRV/hlsl-intrinsics/rcp.ll | 66 ++++++------- 10 files changed, 260 insertions(+), 151 deletions(-) create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/lerp.ll diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index afe2de5d00ac..7e5f2edfc732 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -18267,8 +18267,8 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, if (!E->getArg(0)->getType()->hasFloatingRepresentation()) llvm_unreachable("lerp operand must have a float representation"); return Builder.CreateIntrinsic( - /*ReturnType=*/X->getType(), Intrinsic::dx_lerp, - ArrayRef{X, Y, S}, nullptr, "dx.lerp"); + /*ReturnType=*/X->getType(), CGM.getHLSLRuntime().getLerpIntrinsic(), + ArrayRef{X, Y, S}, nullptr, "hlsl.lerp"); } case Builtin::BI__builtin_hlsl_elementwise_frac: { Value *Op0 = EmitScalarExpr(E->getArg(0)); diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h b/clang/lib/CodeGen/CGHLSLRuntime.h index 506b364f5b2e..0abe39dedcb9 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.h +++ b/clang/lib/CodeGen/CGHLSLRuntime.h @@ -74,6 +74,7 @@ public: GENERATE_HLSL_INTRINSIC_FUNCTION(All, all) GENERATE_HLSL_INTRINSIC_FUNCTION(Any, any) + GENERATE_HLSL_INTRINSIC_FUNCTION(Lerp, lerp) GENERATE_HLSL_INTRINSIC_FUNCTION(ThreadId, thread_id) //===----------------------------------------------------------------------===// diff --git a/clang/test/CodeGenHLSL/builtins/lerp-builtin.hlsl b/clang/test/CodeGenHLSL/builtins/lerp-builtin.hlsl index 2fd5a19fc335..cdc9abbd70e4 100644 --- a/clang/test/CodeGenHLSL/builtins/lerp-builtin.hlsl +++ b/clang/test/CodeGenHLSL/builtins/lerp-builtin.hlsl @@ -1,15 +1,15 @@ // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.3-library %s -fnative-half-type -emit-llvm -disable-llvm-passes -o - | FileCheck %s // CHECK-LABEL: builtin_lerp_half_vector -// CHECK: %dx.lerp = call <3 x half> @llvm.dx.lerp.v3f16(<3 x half> %0, <3 x half> %1, <3 x half> %2) -// CHECK: ret <3 x half> %dx.lerp +// CHECK: %hlsl.lerp = call <3 x half> @llvm.dx.lerp.v3f16(<3 x half> %0, <3 x half> %1, <3 x half> %2) +// CHECK: ret <3 x half> %hlsl.lerp half3 builtin_lerp_half_vector (half3 p0) { return __builtin_hlsl_lerp ( p0, p0, p0 ); } // CHECK-LABEL: builtin_lerp_floar_vector -// CHECK: %dx.lerp = call <2 x float> @llvm.dx.lerp.v2f32(<2 x float> %0, <2 x float> %1, <2 x float> %2) -// CHECK: ret <2 x float> %dx.lerp +// CHECK: %hlsl.lerp = call <2 x float> @llvm.dx.lerp.v2f32(<2 x float> %0, <2 x float> %1, <2 x float> %2) +// CHECK: ret <2 x float> %hlsl.lerp float2 builtin_lerp_floar_vector ( float2 p0) { return __builtin_hlsl_lerp ( p0, p0, p0 ); } diff --git a/clang/test/CodeGenHLSL/builtins/lerp.hlsl b/clang/test/CodeGenHLSL/builtins/lerp.hlsl index 49cd04a10115..634b20be3a28 100644 --- a/clang/test/CodeGenHLSL/builtins/lerp.hlsl +++ b/clang/test/CodeGenHLSL/builtins/lerp.hlsl @@ -1,69 +1,92 @@ // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ // RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \ // RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \ -// RUN: --check-prefixes=CHECK,NATIVE_HALF +// RUN: --check-prefixes=CHECK,DXIL_CHECK,DXIL_NATIVE_HALF,NATIVE_HALF // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ // RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \ -// RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF +// RUN: -o - | FileCheck %s --check-prefixes=CHECK,DXIL_CHECK,NO_HALF,DXIL_NO_HALF +// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ +// RUN: spirv-unknown-vulkan-compute %s -fnative-half-type \ +// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \ +// RUN: --check-prefixes=CHECK,NATIVE_HALF,SPIR_NATIVE_HALF,SPIR_CHECK +// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ +// RUN: spirv-unknown-vulkan-compute %s -emit-llvm -disable-llvm-passes \ +// RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF,SPIR_NO_HALF,SPIR_CHECK -// NATIVE_HALF: %dx.lerp = call half @llvm.dx.lerp.f16(half %0, half %1, half %2) -// NATIVE_HALF: ret half %dx.lerp -// NO_HALF: %dx.lerp = call float @llvm.dx.lerp.f32(float %0, float %1, float %2) -// NO_HALF: ret float %dx.lerp +// DXIL_NATIVE_HALF: %hlsl.lerp = call half @llvm.dx.lerp.f16(half %0, half %1, half %2) +// SPIR_NATIVE_HALF: %hlsl.lerp = call half @llvm.spv.lerp.f16(half %0, half %1, half %2) +// NATIVE_HALF: ret half %hlsl.lerp +// DXIL_NO_HALF: %hlsl.lerp = call float @llvm.dx.lerp.f32(float %0, float %1, float %2) +// SPIR_NO_HALF: %hlsl.lerp = call float @llvm.spv.lerp.f32(float %0, float %1, float %2) +// NO_HALF: ret float %hlsl.lerp half test_lerp_half(half p0) { return lerp(p0, p0, p0); } -// NATIVE_HALF: %dx.lerp = call <2 x half> @llvm.dx.lerp.v2f16(<2 x half> %0, <2 x half> %1, <2 x half> %2) -// NATIVE_HALF: ret <2 x half> %dx.lerp -// NO_HALF: %dx.lerp = call <2 x float> @llvm.dx.lerp.v2f32(<2 x float> %0, <2 x float> %1, <2 x float> %2) -// NO_HALF: ret <2 x float> %dx.lerp +// DXIL_NATIVE_HALF: %hlsl.lerp = call <2 x half> @llvm.dx.lerp.v2f16(<2 x half> %0, <2 x half> %1, <2 x half> %2) +// SPIR_NATIVE_HALF: %hlsl.lerp = call <2 x half> @llvm.spv.lerp.v2f16(<2 x half> %0, <2 x half> %1, <2 x half> %2) +// NATIVE_HALF: ret <2 x half> %hlsl.lerp +// DXIL_NO_HALF: %hlsl.lerp = call <2 x float> @llvm.dx.lerp.v2f32(<2 x float> %0, <2 x float> %1, <2 x float> %2) +// SPIR_NO_HALF: %hlsl.lerp = call <2 x float> @llvm.spv.lerp.v2f32(<2 x float> %0, <2 x float> %1, <2 x float> %2) +// NO_HALF: ret <2 x float> %hlsl.lerp half2 test_lerp_half2(half2 p0) { return lerp(p0, p0, p0); } -// NATIVE_HALF: %dx.lerp = call <3 x half> @llvm.dx.lerp.v3f16(<3 x half> %0, <3 x half> %1, <3 x half> %2) -// NATIVE_HALF: ret <3 x half> %dx.lerp -// NO_HALF: %dx.lerp = call <3 x float> @llvm.dx.lerp.v3f32(<3 x float> %0, <3 x float> %1, <3 x float> %2) -// NO_HALF: ret <3 x float> %dx.lerp +// DXIL_NATIVE_HALF: %hlsl.lerp = call <3 x half> @llvm.dx.lerp.v3f16(<3 x half> %0, <3 x half> %1, <3 x half> %2) +// SPIR_NATIVE_HALF: %hlsl.lerp = call <3 x half> @llvm.spv.lerp.v3f16(<3 x half> %0, <3 x half> %1, <3 x half> %2) +// NATIVE_HALF: ret <3 x half> %hlsl.lerp +// DXIL_NO_HALF: %hlsl.lerp = call <3 x float> @llvm.dx.lerp.v3f32(<3 x float> %0, <3 x float> %1, <3 x float> %2) +// SPIR_NO_HALF: %hlsl.lerp = call <3 x float> @llvm.spv.lerp.v3f32(<3 x float> %0, <3 x float> %1, <3 x float> %2) +// NO_HALF: ret <3 x float> %hlsl.lerp half3 test_lerp_half3(half3 p0) { return lerp(p0, p0, p0); } -// NATIVE_HALF: %dx.lerp = call <4 x half> @llvm.dx.lerp.v4f16(<4 x half> %0, <4 x half> %1, <4 x half> %2) -// NATIVE_HALF: ret <4 x half> %dx.lerp -// NO_HALF: %dx.lerp = call <4 x float> @llvm.dx.lerp.v4f32(<4 x float> %0, <4 x float> %1, <4 x float> %2) -// NO_HALF: ret <4 x float> %dx.lerp +// DXIL_NATIVE_HALF: %hlsl.lerp = call <4 x half> @llvm.dx.lerp.v4f16(<4 x half> %0, <4 x half> %1, <4 x half> %2) +// SPIR_NATIVE_HALF: %hlsl.lerp = call <4 x half> @llvm.spv.lerp.v4f16(<4 x half> %0, <4 x half> %1, <4 x half> %2) +// NATIVE_HALF: ret <4 x half> %hlsl.lerp +// DXIL_NO_HALF: %hlsl.lerp = call <4 x float> @llvm.dx.lerp.v4f32(<4 x float> %0, <4 x float> %1, <4 x float> %2) +// SPIR_NO_HALF: %hlsl.lerp = call <4 x float> @llvm.spv.lerp.v4f32(<4 x float> %0, <4 x float> %1, <4 x float> %2) +// NO_HALF: ret <4 x float> %hlsl.lerp half4 test_lerp_half4(half4 p0) { return lerp(p0, p0, p0); } -// CHECK: %dx.lerp = call float @llvm.dx.lerp.f32(float %0, float %1, float %2) -// CHECK: ret float %dx.lerp +// DXIL_CHECK: %hlsl.lerp = call float @llvm.dx.lerp.f32(float %0, float %1, float %2) +// SPIR_CHECK: %hlsl.lerp = call float @llvm.spv.lerp.f32(float %0, float %1, float %2) +// CHECK: ret float %hlsl.lerp float test_lerp_float(float p0) { return lerp(p0, p0, p0); } -// CHECK: %dx.lerp = call <2 x float> @llvm.dx.lerp.v2f32(<2 x float> %0, <2 x float> %1, <2 x float> %2) -// CHECK: ret <2 x float> %dx.lerp +// DXIL_CHECK: %hlsl.lerp = call <2 x float> @llvm.dx.lerp.v2f32(<2 x float> %0, <2 x float> %1, <2 x float> %2) +// SPIR_CHECK: %hlsl.lerp = call <2 x float> @llvm.spv.lerp.v2f32(<2 x float> %0, <2 x float> %1, <2 x float> %2) +// CHECK: ret <2 x float> %hlsl.lerp float2 test_lerp_float2(float2 p0) { return lerp(p0, p0, p0); } -// CHECK: %dx.lerp = call <3 x float> @llvm.dx.lerp.v3f32(<3 x float> %0, <3 x float> %1, <3 x float> %2) -// CHECK: ret <3 x float> %dx.lerp +// DXIL_CHECK: %hlsl.lerp = call <3 x float> @llvm.dx.lerp.v3f32(<3 x float> %0, <3 x float> %1, <3 x float> %2) +// SPIR_CHECK: %hlsl.lerp = call <3 x float> @llvm.spv.lerp.v3f32(<3 x float> %0, <3 x float> %1, <3 x float> %2) +// CHECK: ret <3 x float> %hlsl.lerp float3 test_lerp_float3(float3 p0) { return lerp(p0, p0, p0); } -// CHECK: %dx.lerp = call <4 x float> @llvm.dx.lerp.v4f32(<4 x float> %0, <4 x float> %1, <4 x float> %2) -// CHECK: ret <4 x float> %dx.lerp +// DXIL_CHECK: %hlsl.lerp = call <4 x float> @llvm.dx.lerp.v4f32(<4 x float> %0, <4 x float> %1, <4 x float> %2) +// SPIR_CHECK: %hlsl.lerp = call <4 x float> @llvm.spv.lerp.v4f32(<4 x float> %0, <4 x float> %1, <4 x float> %2) +// CHECK: ret <4 x float> %hlsl.lerp float4 test_lerp_float4(float4 p0) { return lerp(p0, p0, p0); } -// CHECK: %dx.lerp = call <2 x float> @llvm.dx.lerp.v2f32(<2 x float> %splat.splat, <2 x float> %1, <2 x float> %2) -// CHECK: ret <2 x float> %dx.lerp +// DXIL_CHECK: %hlsl.lerp = call <2 x float> @llvm.dx.lerp.v2f32(<2 x float> %splat.splat, <2 x float> %1, <2 x float> %2) +// SPIR_CHECK: %hlsl.lerp = call <2 x float> @llvm.spv.lerp.v2f32(<2 x float> %splat.splat, <2 x float> %1, <2 x float> %2) +// CHECK: ret <2 x float> %hlsl.lerp float2 test_lerp_float2_splat(float p0, float2 p1) { return lerp(p0, p1, p1); } -// CHECK: %dx.lerp = call <3 x float> @llvm.dx.lerp.v3f32(<3 x float> %splat.splat, <3 x float> %1, <3 x float> %2) -// CHECK: ret <3 x float> %dx.lerp +// DXIL_CHECK: %hlsl.lerp = call <3 x float> @llvm.dx.lerp.v3f32(<3 x float> %splat.splat, <3 x float> %1, <3 x float> %2) +// SPIR_CHECK: %hlsl.lerp = call <3 x float> @llvm.spv.lerp.v3f32(<3 x float> %splat.splat, <3 x float> %1, <3 x float> %2) +// CHECK: ret <3 x float> %hlsl.lerp float3 test_lerp_float3_splat(float p0, float3 p1) { return lerp(p0, p1, p1); } -// CHECK: %dx.lerp = call <4 x float> @llvm.dx.lerp.v4f32(<4 x float> %splat.splat, <4 x float> %1, <4 x float> %2) -// CHECK: ret <4 x float> %dx.lerp +// DXIL_CHECK: %hlsl.lerp = call <4 x float> @llvm.dx.lerp.v4f32(<4 x float> %splat.splat, <4 x float> %1, <4 x float> %2) +// SPIR_CHECK: %hlsl.lerp = call <4 x float> @llvm.spv.lerp.v4f32(<4 x float> %splat.splat, <4 x float> %1, <4 x float> %2) +// CHECK: ret <4 x float> %hlsl.lerp float4 test_lerp_float4_splat(float p0, float4 p1) { return lerp(p0, p1, p1); } // CHECK: %conv = sitofp i32 %2 to float // CHECK: %splat.splatinsert = insertelement <2 x float> poison, float %conv, i64 0 // CHECK: %splat.splat = shufflevector <2 x float> %splat.splatinsert, <2 x float> poison, <2 x i32> zeroinitializer -// CHECK: %dx.lerp = call <2 x float> @llvm.dx.lerp.v2f32(<2 x float> %0, <2 x float> %1, <2 x float> %splat.splat) -// CHECK: ret <2 x float> %dx.lerp +// DXIL_CHECK: %hlsl.lerp = call <2 x float> @llvm.dx.lerp.v2f32(<2 x float> %0, <2 x float> %1, <2 x float> %splat.splat) +// SPIR_CHECK: %hlsl.lerp = call <2 x float> @llvm.spv.lerp.v2f32(<2 x float> %0, <2 x float> %1, <2 x float> %splat.splat) +// CHECK: ret <2 x float> %hlsl.lerp float2 test_lerp_float2_int_splat(float2 p0, int p1) { return lerp(p0, p0, p1); } @@ -71,8 +94,9 @@ float2 test_lerp_float2_int_splat(float2 p0, int p1) { // CHECK: %conv = sitofp i32 %2 to float // CHECK: %splat.splatinsert = insertelement <3 x float> poison, float %conv, i64 0 // CHECK: %splat.splat = shufflevector <3 x float> %splat.splatinsert, <3 x float> poison, <3 x i32> zeroinitializer -// CHECK: %dx.lerp = call <3 x float> @llvm.dx.lerp.v3f32(<3 x float> %0, <3 x float> %1, <3 x float> %splat.splat) -// CHECK: ret <3 x float> %dx.lerp +// DXIL_CHECK: %hlsl.lerp = call <3 x float> @llvm.dx.lerp.v3f32(<3 x float> %0, <3 x float> %1, <3 x float> %splat.splat) +// SPIR_CHECK: %hlsl.lerp = call <3 x float> @llvm.spv.lerp.v3f32(<3 x float> %0, <3 x float> %1, <3 x float> %splat.splat) +// CHECK: ret <3 x float> %hlsl.lerp float3 test_lerp_float3_int_splat(float3 p0, int p1) { return lerp(p0, p0, p1); } diff --git a/llvm/include/llvm/IR/IntrinsicsSPIRV.td b/llvm/include/llvm/IR/IntrinsicsSPIRV.td index b6618baceb56..8660782d71d9 100644 --- a/llvm/include/llvm/IR/IntrinsicsSPIRV.td +++ b/llvm/include/llvm/IR/IntrinsicsSPIRV.td @@ -58,4 +58,6 @@ let TargetPrefix = "spv" in { Intrinsic<[ llvm_ptr_ty ], [llvm_i8_ty], [IntrWillReturn]>; def int_spv_all : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_any_ty]>; def int_spv_any : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_any_ty]>; + def int_spv_lerp : Intrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty, LLVMMatchType<0>,LLVMMatchType<0>], + [IntrNoMem, IntrWillReturn] >; } diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp index 72e5a7bcac98..21a69fc3ad9b 100644 --- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp @@ -170,6 +170,9 @@ private: bool selectFCmp(Register ResVReg, const SPIRVType *ResType, MachineInstr &I) const; + bool selectFmix(Register ResVReg, const SPIRVType *ResType, + MachineInstr &I) const; + void renderImm32(MachineInstrBuilder &MIB, const MachineInstr &I, int OpIdx) const; void renderFImm32(MachineInstrBuilder &MIB, const MachineInstr &I, @@ -1242,6 +1245,27 @@ bool SPIRVInstructionSelector::selectAny(Register ResVReg, return selectAnyOrAll(ResVReg, ResType, I, SPIRV::OpAny); } +bool SPIRVInstructionSelector::selectFmix(Register ResVReg, + const SPIRVType *ResType, + MachineInstr &I) const { + + assert(I.getNumOperands() == 5); + assert(I.getOperand(2).isReg()); + assert(I.getOperand(3).isReg()); + assert(I.getOperand(4).isReg()); + MachineBasicBlock &BB = *I.getParent(); + + return BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpExtInst)) + .addDef(ResVReg) + .addUse(GR.getSPIRVTypeID(ResType)) + .addImm(static_cast(SPIRV::InstructionSet::GLSL_std_450)) + .addImm(GL::FMix) + .addUse(I.getOperand(2).getReg()) + .addUse(I.getOperand(3).getReg()) + .addUse(I.getOperand(4).getReg()) + .constrainAllUses(TII, TRI, RBI); +} + bool SPIRVInstructionSelector::selectBitreverse(Register ResVReg, const SPIRVType *ResType, MachineInstr &I) const { @@ -1902,6 +1926,8 @@ bool SPIRVInstructionSelector::selectIntrinsic(Register ResVReg, return selectAll(ResVReg, ResType, I); case Intrinsic::spv_any: return selectAny(ResVReg, ResType, I); + case Intrinsic::spv_lerp: + return selectFmix(ResVReg, ResType, I); case Intrinsic::spv_lifetime_start: case Intrinsic::spv_lifetime_end: { unsigned Op = IID == Intrinsic::spv_lifetime_start ? SPIRV::OpLifetimeStart diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/all.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/all.ll index ef8d463cbd81..8c5410aa54a4 100644 --- a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/all.ll +++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/all.ll @@ -26,32 +26,32 @@ ; CHECK-HLSL-DAG: %[[#const_i32_0:]] = OpConstant %[[#int_32]] 0 ; CHECK-HLSL-DAG: %[[#const_i16_0:]] = OpConstant %[[#int_16]] 0 ; CHECK-HLSL-DAG: %[[#const_f64_0:]] = OpConstant %[[#float_64]] 0 -; CHECK-HLSL-DAG: %[[#const_f32_0:]] = OpConstant %[[#float_32:]] 0 -; CHECK-HLSL-DAG: %[[#const_f16_0:]] = OpConstant %[[#float_16:]] 0 -; CHECK-HLSL-DAG: %[[#vec4_const_zeros_i16:]] = OpConstantComposite %[[#vec4_16:]] %[[#const_i16_0:]] %[[#const_i16_0:]] %[[#const_i16_0:]] %[[#const_i16_0:]] -; CHECK-HLSL-DAG: %[[#vec4_const_zeros_i32:]] = OpConstantComposite %[[#vec4_32:]] %[[#const_i32_0:]] %[[#const_i32_0:]] %[[#const_i32_0:]] %[[#const_i32_0:]] -; CHECK-HLSL-DAG: %[[#vec4_const_zeros_i64:]] = OpConstantComposite %[[#vec4_64:]] %[[#const_i64_0:]] %[[#const_i64_0:]] %[[#const_i64_0:]] %[[#const_i64_0:]] -; CHECK-HLSL-DAG: %[[#vec4_const_zeros_f16:]] = OpConstantComposite %[[#vec4_float_16:]] %[[#const_f16_0:]] %[[#const_f16_0:]] %[[#const_f16_0:]] %[[#const_f16_0:]] -; CHECK-HLSL-DAG: %[[#vec4_const_zeros_f32:]] = OpConstantComposite %[[#vec4_float_32:]] %[[#const_f32_0:]] %[[#const_f32_0:]] %[[#const_f32_0:]] %[[#const_f32_0:]] -; CHECK-HLSL-DAG: %[[#vec4_const_zeros_f64:]] = OpConstantComposite %[[#vec4_float_64:]] %[[#const_f64_0:]] %[[#const_f64_0:]] %[[#const_f64_0:]] %[[#const_f64_0:]] +; CHECK-HLSL-DAG: %[[#const_f32_0:]] = OpConstant %[[#float_32]] 0 +; CHECK-HLSL-DAG: %[[#const_f16_0:]] = OpConstant %[[#float_16]] 0 +; CHECK-HLSL-DAG: %[[#vec4_const_zeros_i16:]] = OpConstantComposite %[[#vec4_16]] %[[#const_i16_0]] %[[#const_i16_0]] %[[#const_i16_0]] %[[#const_i16_0]] +; CHECK-HLSL-DAG: %[[#vec4_const_zeros_i32:]] = OpConstantComposite %[[#vec4_32]] %[[#const_i32_0]] %[[#const_i32_0]] %[[#const_i32_0]] %[[#const_i32_0]] +; CHECK-HLSL-DAG: %[[#vec4_const_zeros_i64:]] = OpConstantComposite %[[#vec4_64]] %[[#const_i64_0]] %[[#const_i64_0]] %[[#const_i64_0]] %[[#const_i64_0]] +; CHECK-HLSL-DAG: %[[#vec4_const_zeros_f16:]] = OpConstantComposite %[[#vec4_float_16]] %[[#const_f16_0]] %[[#const_f16_0]] %[[#const_f16_0]] %[[#const_f16_0]] +; CHECK-HLSL-DAG: %[[#vec4_const_zeros_f32:]] = OpConstantComposite %[[#vec4_float_32]] %[[#const_f32_0]] %[[#const_f32_0]] %[[#const_f32_0]] %[[#const_f32_0]] +; CHECK-HLSL-DAG: %[[#vec4_const_zeros_f64:]] = OpConstantComposite %[[#vec4_float_64]] %[[#const_f64_0]] %[[#const_f64_0]] %[[#const_f64_0]] %[[#const_f64_0]] ; CHECK-OCL-DAG: %[[#const_i64_0:]] = OpConstantNull %[[#int_64]] ; CHECK-OCL-DAG: %[[#const_i32_0:]] = OpConstantNull %[[#int_32]] ; CHECK-OCL-DAG: %[[#const_i16_0:]] = OpConstantNull %[[#int_16]] ; CHECK-OCL-DAG: %[[#const_f64_0:]] = OpConstantNull %[[#float_64]] -; CHECK-OCL-DAG: %[[#const_f32_0:]] = OpConstantNull %[[#float_32:]] -; CHECK-OCL-DAG: %[[#const_f16_0:]] = OpConstantNull %[[#float_16:]] -; CHECK-OCL-DAG: %[[#vec4_const_zeros_i16:]] = OpConstantNull %[[#vec4_16:]] -; CHECK-OCL-DAG: %[[#vec4_const_zeros_i32:]] = OpConstantNull %[[#vec4_32:]] -; CHECK-OCL-DAG: %[[#vec4_const_zeros_i64:]] = OpConstantNull %[[#vec4_64:]] -; CHECK-OCL-DAG: %[[#vec4_const_zeros_f16:]] = OpConstantNull %[[#vec4_float_16:]] -; CHECK-OCL-DAG: %[[#vec4_const_zeros_f32:]] = OpConstantNull %[[#vec4_float_32:]] -; CHECK-OCL-DAG: %[[#vec4_const_zeros_f64:]] = OpConstantNull %[[#vec4_float_64:]] +; CHECK-OCL-DAG: %[[#const_f32_0:]] = OpConstantNull %[[#float_32]] +; CHECK-OCL-DAG: %[[#const_f16_0:]] = OpConstantNull %[[#float_16]] +; CHECK-OCL-DAG: %[[#vec4_const_zeros_i16:]] = OpConstantNull %[[#vec4_16]] +; CHECK-OCL-DAG: %[[#vec4_const_zeros_i32:]] = OpConstantNull %[[#vec4_32]] +; CHECK-OCL-DAG: %[[#vec4_const_zeros_i64:]] = OpConstantNull %[[#vec4_64]] +; CHECK-OCL-DAG: %[[#vec4_const_zeros_f16:]] = OpConstantNull %[[#vec4_float_16]] +; CHECK-OCL-DAG: %[[#vec4_const_zeros_f32:]] = OpConstantNull %[[#vec4_float_32]] +; CHECK-OCL-DAG: %[[#vec4_const_zeros_f64:]] = OpConstantNull %[[#vec4_float_64]] define noundef i1 @all_int64_t(i64 noundef %p0) { entry: ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] - ; CHECK: %[[#]] = OpINotEqual %[[#bool:]] %[[#arg0:]] %[[#const_i64_0:]] + ; CHECK: %[[#]] = OpINotEqual %[[#bool]] %[[#arg0]] %[[#const_i64_0]] %hlsl.all = call i1 @llvm.spv.all.i64(i64 %p0) ret i1 %hlsl.all } @@ -60,7 +60,7 @@ entry: define noundef i1 @all_int(i32 noundef %p0) { entry: ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] - ; CHECK: %[[#]] = OpINotEqual %[[#bool:]] %[[#arg0:]] %[[#const_i32_0:]] + ; CHECK: %[[#]] = OpINotEqual %[[#bool]] %[[#arg0]] %[[#const_i32_0]] %hlsl.all = call i1 @llvm.spv.all.i32(i32 %p0) ret i1 %hlsl.all } @@ -69,7 +69,7 @@ entry: define noundef i1 @all_int16_t(i16 noundef %p0) { entry: ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] - ; CHECK: %[[#]] = OpINotEqual %[[#bool:]] %[[#arg0:]] %[[#const_i16_0:]] + ; CHECK: %[[#]] = OpINotEqual %[[#bool]] %[[#arg0]] %[[#const_i16_0]] %hlsl.all = call i1 @llvm.spv.all.i16(i16 %p0) ret i1 %hlsl.all } @@ -77,7 +77,7 @@ entry: define noundef i1 @all_double(double noundef %p0) { entry: ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] - ; CHECK: %[[#]] = OpFOrdNotEqual %[[#bool:]] %[[#arg0:]] %[[#const_f64_0:]] + ; CHECK: %[[#]] = OpFOrdNotEqual %[[#bool]] %[[#arg0]] %[[#const_f64_0]] %hlsl.all = call i1 @llvm.spv.all.f64(double %p0) ret i1 %hlsl.all } @@ -86,7 +86,7 @@ entry: define noundef i1 @all_float(float noundef %p0) { entry: ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] - ; CHECK: %[[#]] = OpFOrdNotEqual %[[#bool:]] %[[#arg0:]] %[[#const_f32_0:]] + ; CHECK: %[[#]] = OpFOrdNotEqual %[[#bool]] %[[#arg0]] %[[#const_f32_0]] %hlsl.all = call i1 @llvm.spv.all.f32(float %p0) ret i1 %hlsl.all } @@ -95,7 +95,7 @@ entry: define noundef i1 @all_half(half noundef %p0) { entry: ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] - ; CHECK: %[[#]] = OpFOrdNotEqual %[[#bool:]] %[[#arg0:]] %[[#const_f16_0:]] + ; CHECK: %[[#]] = OpFOrdNotEqual %[[#bool]] %[[#arg0]] %[[#const_f16_0]] %hlsl.all = call i1 @llvm.spv.all.f16(half %p0) ret i1 %hlsl.all } @@ -103,8 +103,8 @@ entry: define noundef i1 @all_bool4(<4 x i1> noundef %p0) { entry: - ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] - ; CHECK: %[[#]] = OpAll %[[#vec4_bool:]] %[[#arg0:]] + ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#vec4_bool]] + ; CHECK: %[[#]] = OpAll %[[#bool]] %[[#arg0]] %hlsl.all = call i1 @llvm.spv.all.v4i1(<4 x i1> %p0) ret i1 %hlsl.all } @@ -112,8 +112,8 @@ entry: define noundef i1 @all_short4(<4 x i16> noundef %p0) { entry: ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] - ; CHECK: %[[#shortVecNotEq:]] = OpINotEqual %[[#vec4_bool:]] %[[#arg0:]] %[[#vec4_const_zeros_i16:]] - ; CHECK: %[[#]] = OpAll %[[#bool:]] %[[#shortVecNotEq:]] + ; CHECK: %[[#shortVecNotEq:]] = OpINotEqual %[[#vec4_bool]] %[[#arg0]] %[[#vec4_const_zeros_i16]] + ; CHECK: %[[#]] = OpAll %[[#bool]] %[[#shortVecNotEq]] %hlsl.all = call i1 @llvm.spv.all.v4i16(<4 x i16> %p0) ret i1 %hlsl.all } @@ -121,8 +121,8 @@ entry: define noundef i1 @all_int4(<4 x i32> noundef %p0) { entry: ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] - ; CHECK: %[[#i32VecNotEq:]] = OpINotEqual %[[#vec4_bool:]] %[[#arg0:]] %[[#vec4_const_zeros_i32:]] - ; CHECK: %[[#]] = OpAll %[[#bool:]] %[[#i32VecNotEq:]] + ; CHECK: %[[#i32VecNotEq:]] = OpINotEqual %[[#vec4_bool]] %[[#arg0]] %[[#vec4_const_zeros_i32]] + ; CHECK: %[[#]] = OpAll %[[#bool]] %[[#i32VecNotEq]] %hlsl.all = call i1 @llvm.spv.all.v4i32(<4 x i32> %p0) ret i1 %hlsl.all } @@ -130,8 +130,8 @@ entry: define noundef i1 @all_int64_t4(<4 x i64> noundef %p0) { entry: ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] - ; CHECK: %[[#i64VecNotEq:]] = OpINotEqual %[[#vec4_bool:]] %[[#arg0:]] %[[#vec4_const_zeros_i64:]] - ; CHECK: %[[#]] = OpAll %[[#bool:]] %[[#i64VecNotEq]] + ; CHECK: %[[#i64VecNotEq:]] = OpINotEqual %[[#vec4_bool]] %[[#arg0]] %[[#vec4_const_zeros_i64]] + ; CHECK: %[[#]] = OpAll %[[#bool]] %[[#i64VecNotEq]] %hlsl.all = call i1 @llvm.spv.all.v4i64(<4 x i64> %p0) ret i1 %hlsl.all } @@ -139,8 +139,8 @@ entry: define noundef i1 @all_half4(<4 x half> noundef %p0) { entry: ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] - ; CHECK: %[[#f16VecNotEq:]] = OpFOrdNotEqual %[[#vec4_bool:]] %[[#arg0:]] %[[#vec4_const_zeros_f16:]] - ; CHECK: %[[#]] = OpAll %[[#bool]] %[[#f16VecNotEq:]] + ; CHECK: %[[#f16VecNotEq:]] = OpFOrdNotEqual %[[#vec4_bool]] %[[#arg0]] %[[#vec4_const_zeros_f16]] + ; CHECK: %[[#]] = OpAll %[[#bool]] %[[#f16VecNotEq]] %hlsl.all = call i1 @llvm.spv.all.v4f16(<4 x half> %p0) ret i1 %hlsl.all } @@ -148,8 +148,8 @@ entry: define noundef i1 @all_float4(<4 x float> noundef %p0) { entry: ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] - ; CHECK: %[[#f32VecNotEq:]] = OpFOrdNotEqual %[[#vec4_bool:]] %[[#arg0:]] %[[#vec4_const_zeros_f32:]] - ; CHECK: %[[#]] = OpAll %[[#bool:]] %[[#f32VecNotEq:]] + ; CHECK: %[[#f32VecNotEq:]] = OpFOrdNotEqual %[[#vec4_bool]] %[[#arg0]] %[[#vec4_const_zeros_f32]] + ; CHECK: %[[#]] = OpAll %[[#bool]] %[[#f32VecNotEq]] %hlsl.all = call i1 @llvm.spv.all.v4f32(<4 x float> %p0) ret i1 %hlsl.all } @@ -157,16 +157,16 @@ entry: define noundef i1 @all_double4(<4 x double> noundef %p0) { entry: ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] - ; CHECK: %[[#f64VecNotEq:]] = OpFOrdNotEqual %[[#vec4_bool:]] %[[#arg0:]] %[[#vec4_const_zeros_f64:]] - ; CHECK: %[[#]] = OpAll %[[#bool:]] %[[#f64VecNotEq:]] + ; CHECK: %[[#f64VecNotEq:]] = OpFOrdNotEqual %[[#vec4_bool]] %[[#arg0]] %[[#vec4_const_zeros_f64]] + ; CHECK: %[[#]] = OpAll %[[#bool]] %[[#f64VecNotEq]] %hlsl.all = call i1 @llvm.spv.all.v4f64(<4 x double> %p0) ret i1 %hlsl.all } define noundef i1 @all_bool(i1 noundef %a) { entry: - ; CHECK: %[[#all_bool_arg:]] = OpFunctionParameter %[[#bool:]] - ; CHECK: OpReturnValue %[[#all_bool_arg:]] + ; CHECK: %[[#all_bool_arg:]] = OpFunctionParameter %[[#bool]] + ; CHECK: OpReturnValue %[[#all_bool_arg]] %hlsl.all = call i1 @llvm.spv.all.i1(i1 %a) ret i1 %hlsl.all } diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/any.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/any.ll index b1dd388f5c6e..7a74a335a659 100644 --- a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/any.ll +++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/any.ll @@ -26,32 +26,32 @@ ; CHECK-HLSL-DAG: %[[#const_i32_0:]] = OpConstant %[[#int_32]] 0 ; CHECK-HLSL-DAG: %[[#const_i16_0:]] = OpConstant %[[#int_16]] 0 ; CHECK-HLSL-DAG: %[[#const_f64_0:]] = OpConstant %[[#float_64]] 0 -; CHECK-HLSL-DAG: %[[#const_f32_0:]] = OpConstant %[[#float_32:]] 0 -; CHECK-HLSL-DAG: %[[#const_f16_0:]] = OpConstant %[[#float_16:]] 0 -; CHECK-HLSL-DAG: %[[#vec4_const_zeros_i16:]] = OpConstantComposite %[[#vec4_16:]] %[[#const_i16_0:]] %[[#const_i16_0:]] %[[#const_i16_0:]] %[[#const_i16_0:]] -; CHECK-HLSL-DAG: %[[#vec4_const_zeros_i32:]] = OpConstantComposite %[[#vec4_32:]] %[[#const_i32_0:]] %[[#const_i32_0:]] %[[#const_i32_0:]] %[[#const_i32_0:]] -; CHECK-HLSL-DAG: %[[#vec4_const_zeros_i64:]] = OpConstantComposite %[[#vec4_64:]] %[[#const_i64_0:]] %[[#const_i64_0:]] %[[#const_i64_0:]] %[[#const_i64_0:]] -; CHECK-HLSL-DAG: %[[#vec4_const_zeros_f16:]] = OpConstantComposite %[[#vec4_float_16:]] %[[#const_f16_0:]] %[[#const_f16_0:]] %[[#const_f16_0:]] %[[#const_f16_0:]] -; CHECK-HLSL-DAG: %[[#vec4_const_zeros_f32:]] = OpConstantComposite %[[#vec4_float_32:]] %[[#const_f32_0:]] %[[#const_f32_0:]] %[[#const_f32_0:]] %[[#const_f32_0:]] -; CHECK-HLSL-DAG: %[[#vec4_const_zeros_f64:]] = OpConstantComposite %[[#vec4_float_64:]] %[[#const_f64_0:]] %[[#const_f64_0:]] %[[#const_f64_0:]] %[[#const_f64_0:]] +; CHECK-HLSL-DAG: %[[#const_f32_0:]] = OpConstant %[[#float_32]] 0 +; CHECK-HLSL-DAG: %[[#const_f16_0:]] = OpConstant %[[#float_16]] 0 +; CHECK-HLSL-DAG: %[[#vec4_const_zeros_i16:]] = OpConstantComposite %[[#vec4_16]] %[[#const_i16_0]] %[[#const_i16_0]] %[[#const_i16_0]] %[[#const_i16_0]] +; CHECK-HLSL-DAG: %[[#vec4_const_zeros_i32:]] = OpConstantComposite %[[#vec4_32]] %[[#const_i32_0]] %[[#const_i32_0]] %[[#const_i32_0]] %[[#const_i32_0]] +; CHECK-HLSL-DAG: %[[#vec4_const_zeros_i64:]] = OpConstantComposite %[[#vec4_64]] %[[#const_i64_0]] %[[#const_i64_0]] %[[#const_i64_0]] %[[#const_i64_0]] +; CHECK-HLSL-DAG: %[[#vec4_const_zeros_f16:]] = OpConstantComposite %[[#vec4_float_16]] %[[#const_f16_0]] %[[#const_f16_0]] %[[#const_f16_0]] %[[#const_f16_0]] +; CHECK-HLSL-DAG: %[[#vec4_const_zeros_f32:]] = OpConstantComposite %[[#vec4_float_32]] %[[#const_f32_0]] %[[#const_f32_0]] %[[#const_f32_0]] %[[#const_f32_0]] +; CHECK-HLSL-DAG: %[[#vec4_const_zeros_f64:]] = OpConstantComposite %[[#vec4_float_64]] %[[#const_f64_0]] %[[#const_f64_0]] %[[#const_f64_0]] %[[#const_f64_0]] ; CHECK-OCL-DAG: %[[#const_i64_0:]] = OpConstantNull %[[#int_64]] ; CHECK-OCL-DAG: %[[#const_i32_0:]] = OpConstantNull %[[#int_32]] ; CHECK-OCL-DAG: %[[#const_i16_0:]] = OpConstantNull %[[#int_16]] ; CHECK-OCL-DAG: %[[#const_f64_0:]] = OpConstantNull %[[#float_64]] -; CHECK-OCL-DAG: %[[#const_f32_0:]] = OpConstantNull %[[#float_32:]] -; CHECK-OCL-DAG: %[[#const_f16_0:]] = OpConstantNull %[[#float_16:]] -; CHECK-OCL-DAG: %[[#vec4_const_zeros_i16:]] = OpConstantNull %[[#vec4_16:]] -; CHECK-OCL-DAG: %[[#vec4_const_zeros_i32:]] = OpConstantNull %[[#vec4_32:]] -; CHECK-OCL-DAG: %[[#vec4_const_zeros_i64:]] = OpConstantNull %[[#vec4_64:]] -; CHECK-OCL-DAG: %[[#vec4_const_zeros_f16:]] = OpConstantNull %[[#vec4_float_16:]] -; CHECK-OCL-DAG: %[[#vec4_const_zeros_f32:]] = OpConstantNull %[[#vec4_float_32:]] -; CHECK-OCL-DAG: %[[#vec4_const_zeros_f64:]] = OpConstantNull %[[#vec4_float_64:]] +; CHECK-OCL-DAG: %[[#const_f32_0:]] = OpConstantNull %[[#float_32]] +; CHECK-OCL-DAG: %[[#const_f16_0:]] = OpConstantNull %[[#float_16]] +; CHECK-OCL-DAG: %[[#vec4_const_zeros_i16:]] = OpConstantNull %[[#vec4_16]] +; CHECK-OCL-DAG: %[[#vec4_const_zeros_i32:]] = OpConstantNull %[[#vec4_32]] +; CHECK-OCL-DAG: %[[#vec4_const_zeros_i64:]] = OpConstantNull %[[#vec4_64]] +; CHECK-OCL-DAG: %[[#vec4_const_zeros_f16:]] = OpConstantNull %[[#vec4_float_16]] +; CHECK-OCL-DAG: %[[#vec4_const_zeros_f32:]] = OpConstantNull %[[#vec4_float_32]] +; CHECK-OCL-DAG: %[[#vec4_const_zeros_f64:]] = OpConstantNull %[[#vec4_float_64]] define noundef i1 @any_int64_t(i64 noundef %p0) { entry: ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] - ; CHECK: %[[#]] = OpINotEqual %[[#bool:]] %[[#arg0:]] %[[#const_i64_0:]] + ; CHECK: %[[#]] = OpINotEqual %[[#bool]] %[[#arg0]] %[[#const_i64_0]] %hlsl.any = call i1 @llvm.spv.any.i64(i64 %p0) ret i1 %hlsl.any } @@ -60,7 +60,7 @@ entry: define noundef i1 @any_int(i32 noundef %p0) { entry: ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] - ; CHECK: %[[#]] = OpINotEqual %[[#bool:]] %[[#arg0:]] %[[#const_i32_0:]] + ; CHECK: %[[#]] = OpINotEqual %[[#bool]] %[[#arg0]] %[[#const_i32_0]] %hlsl.any = call i1 @llvm.spv.any.i32(i32 %p0) ret i1 %hlsl.any } @@ -69,7 +69,7 @@ entry: define noundef i1 @any_int16_t(i16 noundef %p0) { entry: ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] - ; CHECK: %[[#]] = OpINotEqual %[[#bool:]] %[[#arg0:]] %[[#const_i16_0:]] + ; CHECK: %[[#]] = OpINotEqual %[[#bool]] %[[#arg0]] %[[#const_i16_0]] %hlsl.any = call i1 @llvm.spv.any.i16(i16 %p0) ret i1 %hlsl.any } @@ -77,7 +77,7 @@ entry: define noundef i1 @any_double(double noundef %p0) { entry: ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] - ; CHECK: %[[#]] = OpFOrdNotEqual %[[#bool:]] %[[#arg0:]] %[[#const_f64_0:]] + ; CHECK: %[[#]] = OpFOrdNotEqual %[[#bool]] %[[#arg0]] %[[#const_f64_0]] %hlsl.any = call i1 @llvm.spv.any.f64(double %p0) ret i1 %hlsl.any } @@ -86,7 +86,7 @@ entry: define noundef i1 @any_float(float noundef %p0) { entry: ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] - ; CHECK: %[[#]] = OpFOrdNotEqual %[[#bool:]] %[[#arg0:]] %[[#const_f32_0:]] + ; CHECK: %[[#]] = OpFOrdNotEqual %[[#bool]] %[[#arg0]] %[[#const_f32_0]] %hlsl.any = call i1 @llvm.spv.any.f32(float %p0) ret i1 %hlsl.any } @@ -95,7 +95,7 @@ entry: define noundef i1 @any_half(half noundef %p0) { entry: ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] - ; CHECK: %[[#]] = OpFOrdNotEqual %[[#bool:]] %[[#arg0:]] %[[#const_f16_0:]] + ; CHECK: %[[#]] = OpFOrdNotEqual %[[#bool]] %[[#arg0]] %[[#const_f16_0]] %hlsl.any = call i1 @llvm.spv.any.f16(half %p0) ret i1 %hlsl.any } @@ -103,8 +103,8 @@ entry: define noundef i1 @any_bool4(<4 x i1> noundef %p0) { entry: - ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] - ; CHECK: %[[#]] = OpAny %[[#vec4_bool:]] %[[#arg0:]] + ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#vec4_bool]] + ; CHECK: %[[#]] = OpAny %[[#bool]] %[[#arg0]] %hlsl.any = call i1 @llvm.spv.any.v4i1(<4 x i1> %p0) ret i1 %hlsl.any } @@ -112,8 +112,8 @@ entry: define noundef i1 @any_short4(<4 x i16> noundef %p0) { entry: ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] - ; CHECK: %[[#shortVecNotEq:]] = OpINotEqual %[[#vec4_bool:]] %[[#arg0:]] %[[#vec4_const_zeros_i16:]] - ; CHECK: %[[#]] = OpAny %[[#bool:]] %[[#shortVecNotEq:]] + ; CHECK: %[[#shortVecNotEq:]] = OpINotEqual %[[#vec4_bool]] %[[#arg0]] %[[#vec4_const_zeros_i16]] + ; CHECK: %[[#]] = OpAny %[[#bool]] %[[#shortVecNotEq]] %hlsl.any = call i1 @llvm.spv.any.v4i16(<4 x i16> %p0) ret i1 %hlsl.any } @@ -121,8 +121,8 @@ entry: define noundef i1 @any_int4(<4 x i32> noundef %p0) { entry: ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] - ; CHECK: %[[#i32VecNotEq:]] = OpINotEqual %[[#vec4_bool:]] %[[#arg0:]] %[[#vec4_const_zeros_i32:]] - ; CHECK: %[[#]] = OpAny %[[#bool:]] %[[#i32VecNotEq:]] + ; CHECK: %[[#i32VecNotEq:]] = OpINotEqual %[[#vec4_bool]] %[[#arg0]] %[[#vec4_const_zeros_i32]] + ; CHECK: %[[#]] = OpAny %[[#bool]] %[[#i32VecNotEq]] %hlsl.any = call i1 @llvm.spv.any.v4i32(<4 x i32> %p0) ret i1 %hlsl.any } @@ -130,8 +130,8 @@ entry: define noundef i1 @any_int64_t4(<4 x i64> noundef %p0) { entry: ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] - ; CHECK: %[[#i64VecNotEq:]] = OpINotEqual %[[#vec4_bool:]] %[[#arg0:]] %[[#vec4_const_zeros_i64:]] - ; CHECK: %[[#]] = OpAny %[[#bool:]] %[[#i64VecNotEq]] + ; CHECK: %[[#i64VecNotEq:]] = OpINotEqual %[[#vec4_bool]] %[[#arg0]] %[[#vec4_const_zeros_i64]] + ; CHECK: %[[#]] = OpAny %[[#bool]] %[[#i64VecNotEq]] %hlsl.any = call i1 @llvm.spv.any.v4i64(<4 x i64> %p0) ret i1 %hlsl.any } @@ -139,8 +139,8 @@ entry: define noundef i1 @any_half4(<4 x half> noundef %p0) { entry: ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] - ; CHECK: %[[#f16VecNotEq:]] = OpFOrdNotEqual %[[#vec4_bool:]] %[[#arg0:]] %[[#vec4_const_zeros_f16:]] - ; CHECK: %[[#]] = OpAny %[[#bool]] %[[#f16VecNotEq:]] + ; CHECK: %[[#f16VecNotEq:]] = OpFOrdNotEqual %[[#vec4_bool]] %[[#arg0]] %[[#vec4_const_zeros_f16]] + ; CHECK: %[[#]] = OpAny %[[#bool]] %[[#f16VecNotEq]] %hlsl.any = call i1 @llvm.spv.any.v4f16(<4 x half> %p0) ret i1 %hlsl.any } @@ -148,8 +148,8 @@ entry: define noundef i1 @any_float4(<4 x float> noundef %p0) { entry: ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] - ; CHECK: %[[#f32VecNotEq:]] = OpFOrdNotEqual %[[#vec4_bool:]] %[[#arg0:]] %[[#vec4_const_zeros_f32:]] - ; CHECK: %[[#]] = OpAny %[[#bool:]] %[[#f32VecNotEq:]] + ; CHECK: %[[#f32VecNotEq:]] = OpFOrdNotEqual %[[#vec4_bool]] %[[#arg0]] %[[#vec4_const_zeros_f32]] + ; CHECK: %[[#]] = OpAny %[[#bool]] %[[#f32VecNotEq]] %hlsl.any = call i1 @llvm.spv.any.v4f32(<4 x float> %p0) ret i1 %hlsl.any } @@ -157,16 +157,16 @@ entry: define noundef i1 @any_double4(<4 x double> noundef %p0) { entry: ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] - ; CHECK: %[[#f64VecNotEq:]] = OpFOrdNotEqual %[[#vec4_bool:]] %[[#arg0:]] %[[#vec4_const_zeros_f64:]] - ; CHECK: %[[#]] = OpAny %[[#bool:]] %[[#f64VecNotEq:]] + ; CHECK: %[[#f64VecNotEq:]] = OpFOrdNotEqual %[[#vec4_bool]] %[[#arg0]] %[[#vec4_const_zeros_f64]] + ; CHECK: %[[#]] = OpAny %[[#bool]] %[[#f64VecNotEq]] %hlsl.any = call i1 @llvm.spv.any.v4f64(<4 x double> %p0) ret i1 %hlsl.any } define noundef i1 @any_bool(i1 noundef %a) { entry: - ; CHECK: %[[#any_bool_arg:]] = OpFunctionParameter %[[#bool:]] - ; CHECK: OpReturnValue %[[#any_bool_arg:]] + ; CHECK: %[[#any_bool_arg:]] = OpFunctionParameter %[[#bool]] + ; CHECK: OpReturnValue %[[#any_bool_arg]] %hlsl.any = call i1 @llvm.spv.any.i1(i1 %a) ret i1 %hlsl.any } diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/lerp.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/lerp.ll new file mode 100644 index 000000000000..63547820c18c --- /dev/null +++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/lerp.ll @@ -0,0 +1,56 @@ +; RUN: llc -O0 -mtriple=spirv-unknown-unknown %s -o - | FileCheck %s +; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-unknown %s -o - -filetype=obj | spirv-val %} + +; Make sure SPIRV operation function calls for lerp are generated as FMix + +; CHECK-DAG: %[[#op_ext_glsl:]] = OpExtInstImport "GLSL.std.450" +; CHECK-DAG: %[[#float_32:]] = OpTypeFloat 32 +; CHECK-DAG: %[[#float_16:]] = OpTypeFloat 16 +; CHECK-DAG: %[[#vec4_float_16:]] = OpTypeVector %[[#float_16]] 4 +; CHECK-DAG: %[[#vec4_float_32:]] = OpTypeVector %[[#float_32]] 4 + +define noundef half @lerp_half(half noundef %a, half noundef %b, half noundef %c) { +entry: + ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] + ; CHECK: %[[#arg1:]] = OpFunctionParameter %[[#]] + ; CHECK: %[[#arg2:]] = OpFunctionParameter %[[#]] + ; CHECK: %[[#]] = OpExtInst %[[#float_16]] %[[#op_ext_glsl]] FMix %[[#arg0]] %[[#arg1]] %[[#arg2]] + %hlsl.lerp = call half @llvm.spv.lerp.f16(half %a, half %b, half %c) + ret half %hlsl.lerp +} + + +define noundef float @lerp_float(float noundef %a, float noundef %b, float noundef %c) { +entry: + ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] + ; CHECK: %[[#arg1:]] = OpFunctionParameter %[[#]] + ; CHECK: %[[#arg2:]] = OpFunctionParameter %[[#]] + ; CHECK: %[[#]] = OpExtInst %[[#float_32]] %[[#op_ext_glsl]] FMix %[[#arg0]] %[[#arg1]] %[[#arg2]] + %hlsl.lerp = call float @llvm.spv.lerp.f32(float %a, float %b, float %c) + ret float %hlsl.lerp +} + +define noundef <4 x half> @lerp_half4(<4 x half> noundef %a, <4 x half> noundef %b, <4 x half> noundef %c) { +entry: + ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] + ; CHECK: %[[#arg1:]] = OpFunctionParameter %[[#]] + ; CHECK: %[[#arg2:]] = OpFunctionParameter %[[#]] + ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_16]] %[[#op_ext_glsl]] FMix %[[#arg0]] %[[#arg1]] %[[#arg2]] + %hlsl.lerp = call <4 x half> @llvm.spv.lerp.v4f16(<4 x half> %a, <4 x half> %b, <4 x half> %c) + ret <4 x half> %hlsl.lerp +} + +define noundef <4 x float> @lerp_float4(<4 x float> noundef %a, <4 x float> noundef %b, <4 x float> noundef %c) { +entry: + ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] + ; CHECK: %[[#arg1:]] = OpFunctionParameter %[[#]] + ; CHECK: %[[#arg2:]] = OpFunctionParameter %[[#]] + ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_32]] %[[#op_ext_glsl]] FMix %[[#arg0]] %[[#arg1]] %[[#arg2]] + %hlsl.lerp = call <4 x float> @llvm.spv.lerp.v4f32(<4 x float> %a, <4 x float> %b, <4 x float> %c) + ret <4 x float> %hlsl.lerp +} + +declare half @llvm.spv.lerp.f16(half, half, half) +declare float @llvm.spv.lerp.f32(float, float, float) +declare <4 x half> @llvm.spv.lerp.v4f16(<4 x half>, <4 x half>, <4 x half>) +declare <4 x float> @llvm.spv.lerp.v4f32(<4 x float>, <4 x float>, <4 x float>) diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/rcp.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/rcp.ll index 95962c0fdc96..34f3c610ca81 100644 --- a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/rcp.ll +++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/rcp.ll @@ -13,90 +13,90 @@ ; CHECK-DAG: %[[#vec4_float_32:]] = OpTypeVector %[[#float_32]] 4 ; CHECK-DAG: %[[#vec4_float_64:]] = OpTypeVector %[[#float_64]] 4 ; CHECK-DAG: %[[#const_f64_1:]] = OpConstant %[[#float_64]] 1 -; CHECK-DAG: %[[#const_f32_1:]] = OpConstant %[[#float_32:]] 1 -; CHECK-DAG: %[[#const_f16_1:]] = OpConstant %[[#float_16:]] 1 +; CHECK-DAG: %[[#const_f32_1:]] = OpConstant %[[#float_32]] 1 +; CHECK-DAG: %[[#const_f16_1:]] = OpConstant %[[#float_16]] 1 -; CHECK-DAG: %[[#vec2_const_ones_f16:]] = OpConstantComposite %[[#vec2_float_16:]] %[[#const_f16_1:]] %[[#const_f16_1:]] -; CHECK-DAG: %[[#vec3_const_ones_f16:]] = OpConstantComposite %[[#vec3_float_16:]] %[[#const_f16_1:]] %[[#const_f16_1:]] %[[#const_f16_1:]] -; CHECK-DAG: %[[#vec4_const_ones_f16:]] = OpConstantComposite %[[#vec4_float_16:]] %[[#const_f16_1:]] %[[#const_f16_1:]] %[[#const_f16_1:]] %[[#const_f16_1:]] +; CHECK-DAG: %[[#vec2_const_ones_f16:]] = OpConstantComposite %[[#vec2_float_16]] %[[#const_f16_1]] %[[#const_f16_1]] +; CHECK-DAG: %[[#vec3_const_ones_f16:]] = OpConstantComposite %[[#vec3_float_16]] %[[#const_f16_1]] %[[#const_f16_1]] %[[#const_f16_1]] +; CHECK-DAG: %[[#vec4_const_ones_f16:]] = OpConstantComposite %[[#vec4_float_16]] %[[#const_f16_1]] %[[#const_f16_1]] %[[#const_f16_1]] %[[#const_f16_1]] -; CHECK-DAG: %[[#vec2_const_ones_f32:]] = OpConstantComposite %[[#vec2_float_32:]] %[[#const_f32_1:]] %[[#const_f32_1:]] -; CHECK-DAG: %[[#vec3_const_ones_f32:]] = OpConstantComposite %[[#vec3_float_32:]] %[[#const_f32_1:]] %[[#const_f32_1:]] %[[#const_f32_1:]] -; CHECK-DAG: %[[#vec4_const_ones_f32:]] = OpConstantComposite %[[#vec4_float_32:]] %[[#const_f32_1:]] %[[#const_f32_1:]] %[[#const_f32_1:]] %[[#const_f32_1:]] +; CHECK-DAG: %[[#vec2_const_ones_f32:]] = OpConstantComposite %[[#vec2_float_32]] %[[#const_f32_1]] %[[#const_f32_1]] +; CHECK-DAG: %[[#vec3_const_ones_f32:]] = OpConstantComposite %[[#vec3_float_32]] %[[#const_f32_1]] %[[#const_f32_1]] %[[#const_f32_1]] +; CHECK-DAG: %[[#vec4_const_ones_f32:]] = OpConstantComposite %[[#vec4_float_32]] %[[#const_f32_1]] %[[#const_f32_1]] %[[#const_f32_1]] %[[#const_f32_1]] -; CHECK-DAG: %[[#vec2_const_ones_f64:]] = OpConstantComposite %[[#vec2_float_64:]] %[[#const_f64_1:]] %[[#const_f64_1:]] -; CHECK-DAG: %[[#vec3_const_ones_f64:]] = OpConstantComposite %[[#vec3_float_64:]] %[[#const_f64_1:]] %[[#const_f64_1:]] %[[#const_f64_1:]] -; CHECK-DAG: %[[#vec4_const_ones_f64:]] = OpConstantComposite %[[#vec4_float_64:]] %[[#const_f64_1:]] %[[#const_f64_1:]] %[[#const_f64_1:]] %[[#const_f64_1:]] +; CHECK-DAG: %[[#vec2_const_ones_f64:]] = OpConstantComposite %[[#vec2_float_64]] %[[#const_f64_1]] %[[#const_f64_1]] +; CHECK-DAG: %[[#vec3_const_ones_f64:]] = OpConstantComposite %[[#vec3_float_64]] %[[#const_f64_1]] %[[#const_f64_1]] %[[#const_f64_1]] +; CHECK-DAG: %[[#vec4_const_ones_f64:]] = OpConstantComposite %[[#vec4_float_64]] %[[#const_f64_1]] %[[#const_f64_1]] %[[#const_f64_1]] %[[#const_f64_1]] define spir_func noundef half @test_rcp_half(half noundef %p0) #0 { entry: - ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#float_16:]] - ; CHECK: OpFDiv %[[#float_16:]] %[[#const_f16_1:]] %[[#arg0:]] + ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#float_16]] + ; CHECK: OpFDiv %[[#float_16]] %[[#const_f16_1]] %[[#arg0]] %hlsl.rcp = fdiv half 0xH3C00, %p0 ret half %hlsl.rcp } define spir_func noundef <2 x half> @test_rcp_half2(<2 x half> noundef %p0) #0 { entry: - ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#vec2_float_16:]] - ; CHECK: OpFDiv %[[#vec2_float_16:]] %[[#vec2_const_ones_f16:]] %[[#arg0:]] + ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#vec2_float_16]] + ; CHECK: OpFDiv %[[#vec2_float_16]] %[[#vec2_const_ones_f16]] %[[#arg0]] %hlsl.rcp = fdiv <2 x half> , %p0 ret <2 x half> %hlsl.rcp } define spir_func noundef <3 x half> @test_rcp_half3(<3 x half> noundef %p0) #0 { entry: - ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#vec3_float_16:]] - ; CHECK: OpFDiv %[[#vec3_float_16:]] %[[#vec3_const_ones_f16:]] %[[#arg0:]] + ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#vec3_float_16]] + ; CHECK: OpFDiv %[[#vec3_float_16]] %[[#vec3_const_ones_f16]] %[[#arg0]] %hlsl.rcp = fdiv <3 x half> , %p0 ret <3 x half> %hlsl.rcp } define spir_func noundef <4 x half> @test_rcp_half4(<4 x half> noundef %p0) #0 { entry: - ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#vec4_float_16:]] - ; CHECK: OpFDiv %[[#vec4_float_16:]] %[[#vec4_const_ones_f16:]] %[[#arg0:]] + ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#vec4_float_16]] + ; CHECK: OpFDiv %[[#vec4_float_16]] %[[#vec4_const_ones_f16]] %[[#arg0]] %hlsl.rcp = fdiv <4 x half> , %p0 ret <4 x half> %hlsl.rcp } define spir_func noundef float @test_rcp_float(float noundef %p0) #0 { entry: - ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#float_32:]] - ; CHECK: OpFDiv %[[#float_32:]] %[[#const_f32_1:]] %[[#arg0:]] + ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#float_32]] + ; CHECK: OpFDiv %[[#float_32]] %[[#const_f32_1]] %[[#arg0]] %hlsl.rcp = fdiv float 1.000000e+00, %p0 ret float %hlsl.rcp } define spir_func noundef <2 x float> @test_rcp_float2(<2 x float> noundef %p0) #0 { entry: - ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#vec2_float_32:]] - ; CHECK: OpFDiv %[[#vec2_float_32:]] %[[#vec2_const_ones_f32:]] %[[#arg0:]] + ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#vec2_float_32]] + ; CHECK: OpFDiv %[[#vec2_float_32]] %[[#vec2_const_ones_f32]] %[[#arg0]] %hlsl.rcp = fdiv <2 x float> , %p0 ret <2 x float> %hlsl.rcp } define spir_func noundef <3 x float> @test_rcp_float3(<3 x float> noundef %p0) #0 { entry: - ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#vec3_float_32:]] - ; CHECK: OpFDiv %[[#vec3_float_32:]] %[[#vec3_const_ones_f32:]] %[[#arg0:]] + ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#vec3_float_32]] + ; CHECK: OpFDiv %[[#vec3_float_32]] %[[#vec3_const_ones_f32]] %[[#arg0]] %hlsl.rcp = fdiv <3 x float> , %p0 ret <3 x float> %hlsl.rcp } define spir_func noundef <4 x float> @test_rcp_float4(<4 x float> noundef %p0) #0 { entry: - ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#vec4_float_32:]] - ; CHECK: OpFDiv %[[#vec4_float_32:]] %[[#vec4_const_ones_f32:]] %[[#arg0:]] + ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#vec4_float_32]] + ; CHECK: OpFDiv %[[#vec4_float_32]] %[[#vec4_const_ones_f32]] %[[#arg0]] %hlsl.rcp = fdiv <4 x float> , %p0 ret <4 x float> %hlsl.rcp } define spir_func noundef double @test_rcp_double(double noundef %p0) #0 { entry: - ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#float_64:]] - ; CHECK: OpFDiv %[[#float_64:]] %[[#const_f64_1:]] %[[#arg0:]] + ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#float_64]] + ; CHECK: OpFDiv %[[#float_64]] %[[#const_f64_1]] %[[#arg0]] %hlsl.rcp = fdiv double 1.000000e+00, %p0 ret double %hlsl.rcp } @@ -104,7 +104,7 @@ entry: define spir_func noundef <2 x double> @test_rcp_double2(<2 x double> noundef %p0) #0 { entry: ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#vec2_float_64:]] - ; CHECK: OpFDiv %[[#vec2_float_64:]] %[[#vec2_const_ones_f64:]] %[[#arg0:]] + ; CHECK: OpFDiv %[[#vec2_float_64]] %[[#vec2_const_ones_f64]] %[[#arg0]] %hlsl.rcp = fdiv <2 x double> , %p0 ret <2 x double> %hlsl.rcp } @@ -112,15 +112,15 @@ entry: define spir_func noundef <3 x double> @test_rcp_double3(<3 x double> noundef %p0) #0 { entry: ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#vec3_float_64:]] - ; CHECK: OpFDiv %[[#vec3_float_64:]] %[[#vec3_const_ones_f64:]] %[[#arg0:]] + ; CHECK: OpFDiv %[[#vec3_float_64]] %[[#vec3_const_ones_f64]] %[[#arg0]] %hlsl.rcp = fdiv <3 x double> , %p0 ret <3 x double> %hlsl.rcp } define spir_func noundef <4 x double> @test_rcp_double4(<4 x double> noundef %p0) #0 { entry: - ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#vec4_float_64:]] - ; CHECK: OpFDiv %[[#vec4_float_64:]] %[[#vec4_const_ones_f64:]] %[[#arg0:]] + ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#vec4_float_64]] + ; CHECK: OpFDiv %[[#vec4_float_64]] %[[#vec4_const_ones_f64]] %[[#arg0]] %hlsl.rcp = fdiv <4 x double> , %p0 ret <4 x double> %hlsl.rcp } -- GitLab From b6628c24ef017138b8d6eb288e94c141e7c846b0 Mon Sep 17 00:00:00 2001 From: Sirraide Date: Mon, 22 Apr 2024 18:41:36 +0200 Subject: [PATCH 002/732] [Clang] Fix crash on invalid size in user-defined `static_assert` message (#89420) This addresses two problems observed in #89407 wrt user-defined `static_assert` messages: 1. In `Expr::EvaluateCharRangeAsString`, we were calling `getExtValue()` instead of `getZExtValue()`, which would assert if a negative or very large number was returned from `size()`. 2. If the value could not be converted to `std::size_t`, attempting to diagnose that would crash because `ext_cce_narrowing` was missing two `%select` cases. This fixes #89407. --- clang/docs/ReleaseNotes.rst | 2 + .../clang/Basic/DiagnosticSemaKinds.td | 6 +- clang/lib/AST/ExprConstant.cpp | 4 +- clang/test/SemaCXX/static-assert-cxx26.cpp | 74 +++++++++++++++++++ 4 files changed, 81 insertions(+), 5 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 009531bae8a9..aea99680c79a 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -555,6 +555,8 @@ Bug Fixes to C++ Support - Fix a crash caused by defined struct in a type alias template when the structure has fields with dependent type. Fixes (#GH75221). - Fix the Itanium mangling of lambdas defined in a member of a local class (#GH88906) +- Fixed a crash when trying to evaluate a user-defined ``static_assert`` message whose ``size()`` + function returns a large or negative value. Fixes (#GH89407). Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index a95424862e63..63e951daec74 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -87,9 +87,9 @@ def err_expr_not_cce : Error< "call to 'size()'|call to 'data()'}0 is not a constant expression">; def ext_cce_narrowing : ExtWarn< "%select{case value|enumerator value|non-type template argument|" - "array size|explicit specifier argument|noexcept specifier argument}0 " - "%select{cannot be narrowed from type %2 to %3|" - "evaluates to %2, which cannot be narrowed to type %3}1">, + "array size|explicit specifier argument|noexcept specifier argument|" + "call to 'size()'|call to 'data()'}0 %select{cannot be narrowed from " + "type %2 to %3|evaluates to %2, which cannot be narrowed to type %3}1">, InGroup, DefaultError, SFINAEFailure; def err_ice_not_integral : Error< "%select{integer|integral}1 constant expression must have " diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 73ae8d8efb23..de3c2a63913e 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -16853,13 +16853,13 @@ bool Expr::EvaluateCharRangeAsString(std::string &Result, if (!::EvaluateInteger(SizeExpression, SizeValue, Info)) return false; - int64_t Size = SizeValue.getExtValue(); + uint64_t Size = SizeValue.getZExtValue(); if (!::EvaluatePointer(PtrExpression, String, Info)) return false; QualType CharTy = PtrExpression->getType()->getPointeeType(); - for (int64_t I = 0; I < Size; ++I) { + for (uint64_t I = 0; I < Size; ++I) { APValue Char; if (!handleLValueToRValueConversion(Info, PtrExpression, CharTy, String, Char)) diff --git a/clang/test/SemaCXX/static-assert-cxx26.cpp b/clang/test/SemaCXX/static-assert-cxx26.cpp index f4ede74f9214..7d896d8b365b 100644 --- a/clang/test/SemaCXX/static-assert-cxx26.cpp +++ b/clang/test/SemaCXX/static-assert-cxx26.cpp @@ -341,3 +341,77 @@ struct Callable { } data; }; static_assert(false, Callable{}); // expected-error {{static assertion failed: hello}} + +namespace GH89407 { +struct A { + constexpr __SIZE_TYPE__ size() const { return -1; } + constexpr const char* data() const { return ""; } +}; + +struct B { + constexpr long long size() const { return 18446744073709551615U; } + constexpr const char* data() const { return ""; } +}; + +struct C { + constexpr __int128 size() const { return -1; } + constexpr const char* data() const { return ""; } +}; + +struct D { + constexpr unsigned __int128 size() const { return -1; } + constexpr const char* data() const { return ""; } +}; + +struct E { + constexpr __SIZE_TYPE__ size() const { return 18446744073709551615U; } + constexpr const char* data() const { return ""; } +}; + +static_assert(true, A{}); // expected-error {{the message in this static assertion is not a constant expression}} + // expected-note@-1 {{read of dereferenced one-past-the-end pointer is not allowed in a constant expression}} +static_assert(true, B{}); // expected-error {{call to 'size()' evaluates to -1, which cannot be narrowed to type 'unsigned long'}} + // expected-error@-1 {{the message in this static assertion is not a constant expression}} + // expected-note@-2 {{read of dereferenced one-past-the-end pointer is not allowed in a constant expression}} +static_assert(true, C{}); // expected-error {{call to 'size()' evaluates to -1, which cannot be narrowed to type 'unsigned long'}} + // expected-error@-1 {{the message in this static assertion is not a constant expression}} + // expected-note@-2 {{read of dereferenced one-past-the-end pointer is not allowed in a constant expression}} +static_assert(true, D{}); // expected-error {{call to 'size()' evaluates to 340282366920938463463374607431768211455, which cannot be narrowed to type 'unsigned long'}} + // expected-error@-1 {{the message in this static assertion is not a constant expression}} + // expected-note@-2 {{read of dereferenced one-past-the-end pointer is not allowed in a constant expression}} +static_assert(true, E{}); // expected-error {{the message in this static assertion is not a constant expression}} + // expected-note@-1 {{read of dereferenced one-past-the-end pointer is not allowed in a constant expression}} + +static_assert( + false, // expected-error {{static assertion failed}} + A{} // expected-error {{the message in a static assertion must be produced by a constant expression}} + // expected-note@-1 {{read of dereferenced one-past-the-end pointer is not allowed in a constant expression}} +); + +static_assert( + false, // expected-error {{static assertion failed}} + B{} // expected-error {{call to 'size()' evaluates to -1, which cannot be narrowed to type 'unsigned long'}} + // expected-error@-1 {{the message in a static assertion must be produced by a constant expression}} + // expected-note@-2 {{read of dereferenced one-past-the-end pointer is not allowed in a constant expression}} +); + +static_assert( + false, // expected-error {{static assertion failed}} + C{} // expected-error {{call to 'size()' evaluates to -1, which cannot be narrowed to type 'unsigned long'}} + // expected-error@-1 {{the message in a static assertion must be produced by a constant expression}} + // expected-note@-2 {{read of dereferenced one-past-the-end pointer is not allowed in a constant expression}} +); + +static_assert( + false, // expected-error {{static assertion failed}} + D{} // expected-error {{call to 'size()' evaluates to 340282366920938463463374607431768211455, which cannot be narrowed to type 'unsigned long'}} + // expected-error@-1 {{the message in a static assertion must be produced by a constant expression}} + // expected-note@-2 {{read of dereferenced one-past-the-end pointer is not allowed in a constant expression}} +); + +static_assert( + false, // expected-error {{static assertion failed}} + E{} // expected-error {{the message in a static assertion must be produced by a constant expression}} + // expected-note@-1 {{read of dereferenced one-past-the-end pointer is not allowed in a constant expression}} +); +} -- GitLab From 330d8983d25d08580fc1642fea48b2473f47a9da Mon Sep 17 00:00:00 2001 From: Johannes Doerfert Date: Mon, 22 Apr 2024 09:51:33 -0700 Subject: [PATCH 003/732] [Offload] Move `/openmp/libomptarget` to `/offload` (#75125) In a nutshell, this moves our libomptarget code to populate the offload subproject. With this commit, users need to enable the new LLVM/Offload subproject as a runtime in their cmake configuration. No further changes are expected for downstream code. Tests and other components still depend on OpenMP and have also not been renamed. The results below are for a build in which OpenMP and Offload are enabled runtimes. In addition to the pure `git mv`, we needed to adjust some CMake files. Nothing is intended to change semantics. ``` ninja check-offload ``` Works with the X86 and AMDGPU offload tests ``` ninja check-openmp ``` Still works but doesn't build offload tests anymore. ``` ls install/lib ``` Shows all expected libraries, incl. - `libomptarget.devicertl.a` - `libomptarget-nvptx-sm_90.bc` - `libomptarget.rtl.amdgpu.so` -> `libomptarget.rtl.amdgpu.so.18git` - `libomptarget.so` -> `libomptarget.so.18git` Fixes: https://github.com/llvm/llvm-project/issues/75124 --------- Co-authored-by: Saiyedul Islam --- llvm/CMakeLists.txt | 2 +- .../libomptarget => offload}/CMakeLists.txt | 166 +++++++++++- .../DeviceRTL/CMakeLists.txt | 4 +- .../DeviceRTL/include/Allocator.h | 0 .../DeviceRTL/include/Configuration.h | 0 .../DeviceRTL/include/Debug.h | 0 .../DeviceRTL/include/Interface.h | 0 .../DeviceRTL/include/LibC.h | 0 .../DeviceRTL/include/Mapping.h | 0 .../DeviceRTL/include/State.h | 0 .../DeviceRTL/include/Synchronization.h | 0 .../DeviceRTL/include/Types.h | 0 .../DeviceRTL/include/Utils.h | 0 .../include/generated_microtask_cases.gen | 0 .../DeviceRTL/src/Allocator.cpp | 0 .../DeviceRTL/src/Configuration.cpp | 0 .../DeviceRTL/src/Debug.cpp | 0 .../DeviceRTL/src/Kernel.cpp | 0 .../DeviceRTL/src/LibC.cpp | 0 .../DeviceRTL/src/Mapping.cpp | 0 .../DeviceRTL/src/Misc.cpp | 0 .../DeviceRTL/src/Parallelism.cpp | 0 .../DeviceRTL/src/Reduction.cpp | 0 .../DeviceRTL/src/State.cpp | 0 .../DeviceRTL/src/Stub.cpp | 0 .../DeviceRTL/src/Synchronization.cpp | 0 .../DeviceRTL/src/Tasking.cpp | 0 .../DeviceRTL/src/Utils.cpp | 0 .../DeviceRTL/src/Workshare.cpp | 0 .../DeviceRTL/src/exports | 0 {openmp/libomptarget => offload}/README.txt | 0 .../Modules/LibomptargetGetDependencies.cmake | 0 .../cmake/Modules/LibomptargetUtils.cmake | 0 offload/cmake/OpenMPTesting.cmake | 238 ++++++++++++++++++ .../docs/declare_target_indirect.md | 0 .../include/DeviceImage.h | 0 .../include/ExclusiveAccess.h | 0 .../include/OffloadEntry.h | 0 .../include/OffloadPolicy.h | 0 .../include/OpenMP/InternalTypes.h | 0 .../include/OpenMP/InteropAPI.h | 0 .../include/OpenMP/Mapping.h | 0 .../include/OpenMP/OMPT/Callback.h | 0 .../include/OpenMP/OMPT/Connector.h | 0 .../include/OpenMP/OMPT/Interface.h | 0 .../include/OpenMP/omp.h | 0 .../include/PluginManager.h | 0 .../include/Shared/APITypes.h | 0 .../include/Shared/Debug.h | 0 .../include/Shared/Environment.h | 0 .../include/Shared/EnvironmentVar.h | 0 .../include/Shared/PluginAPI.h | 0 .../include/Shared/PluginAPI.inc | 0 .../include/Shared/Profile.h | 0 .../include/Shared/Requirements.h | 0 .../include/Shared/SourceInfo.h | 0 .../include/Shared/Utils.h | 0 .../include/Utils/ExponentialBackoff.h | 0 .../libomptarget => offload}/include/device.h | 0 .../include/omptarget.h | 0 .../libomptarget => offload}/include/rtl.h | 0 .../plugins-nextgen/CMakeLists.txt | 0 .../plugins-nextgen/amdgpu/CMakeLists.txt | 2 +- .../amdgpu/dynamic_hsa/hsa.cpp | 0 .../plugins-nextgen/amdgpu/dynamic_hsa/hsa.h | 0 .../amdgpu/dynamic_hsa/hsa_ext_amd.h | 0 .../plugins-nextgen/amdgpu/src/rtl.cpp | 0 .../amdgpu/utils/UtilitiesRTL.h | 0 .../plugins-nextgen/common/CMakeLists.txt | 0 .../common/OMPT/OmptCallback.cpp | 0 .../plugins-nextgen/common/include/DLWrap.h | 0 .../common/include/GlobalHandler.h | 0 .../plugins-nextgen/common/include/JIT.h | 0 .../common/include/MemoryManager.h | 0 .../common/include/PluginInterface.h | 0 .../plugins-nextgen/common/include/RPC.h | 0 .../common/include/Utils/ELF.h | 0 .../common/src/GlobalHandler.cpp | 0 .../plugins-nextgen/common/src/JIT.cpp | 0 .../common/src/PluginInterface.cpp | 0 .../plugins-nextgen/common/src/RPC.cpp | 0 .../plugins-nextgen/common/src/Utils/ELF.cpp | 0 .../plugins-nextgen/cuda/CMakeLists.txt | 2 +- .../cuda/dynamic_cuda/cuda.cpp | 0 .../plugins-nextgen/cuda/dynamic_cuda/cuda.h | 0 .../plugins-nextgen/cuda/src/rtl.cpp | 0 .../plugins-nextgen/exports | 0 .../plugins-nextgen/host/CMakeLists.txt | 2 +- .../plugins-nextgen/host/dynamic_ffi/ffi.cpp | 0 .../plugins-nextgen/host/dynamic_ffi/ffi.h | 0 .../plugins-nextgen/host/src/rtl.cpp | 0 .../src/CMakeLists.txt | 10 +- .../src/DeviceImage.cpp | 0 .../src/LegacyAPI.cpp | 0 .../src/OffloadRTL.cpp | 0 .../src/OpenMP/API.cpp | 0 .../src/OpenMP/InteropAPI.cpp | 0 .../src/OpenMP/Mapping.cpp | 0 .../src/OpenMP/OMPT/Callback.cpp | 0 .../src/PluginManager.cpp | 0 .../libomptarget => offload}/src/device.cpp | 0 {openmp/libomptarget => offload}/src/exports | 0 .../src/interface.cpp | 0 .../src/omptarget.cpp | 0 .../libomptarget => offload}/src/private.h | 0 .../test/CMakeLists.txt | 15 +- .../test/Inputs/basic_array.f90 | 0 .../test/Inputs/declare_indirect_func.c | 0 .../test/api/assert.c | 0 .../test/api/is_initial_device.c | 0 .../test/api/omp_device_managed_memory.c | 0 .../api/omp_device_managed_memory_alloc.c | 0 .../test/api/omp_device_memory.c | 0 .../test/api/omp_dynamic_shared_memory.c | 0 .../api/omp_dynamic_shared_memory_amdgpu.c | 0 .../api/omp_dynamic_shared_memory_mixed.inc | 0 .../omp_dynamic_shared_memory_mixed_amdgpu.c | 0 .../omp_dynamic_shared_memory_mixed_nvptx.c | 0 .../test/api/omp_env_vars.c | 0 .../test/api/omp_get_device_num.c | 0 .../test/api/omp_get_mapped_ptr.c | 0 .../test/api/omp_get_num_devices.c | 0 .../omp_get_num_devices_with_empty_target.c | 0 .../test/api/omp_get_num_procs.c | 0 .../test/api/omp_host_pinned_memory.c | 0 .../test/api/omp_host_pinned_memory_alloc.c | 0 .../test/api/omp_indirect_call.c | 0 .../test/api/omp_target_memcpy_async1.c | 0 .../test/api/omp_target_memcpy_async2.c | 0 .../test/api/omp_target_memcpy_rect_async1.c | 0 .../test/api/omp_target_memcpy_rect_async2.c | 0 .../test/api/omp_target_memset.c | 0 .../test/api/ompx_3d.c | 0 .../test/api/ompx_3d.cpp | 0 .../test/api/ompx_sync.c | 0 .../test/api/ompx_sync.cpp | 0 .../test/env/base_ptr_ref_count.c | 0 .../test/env/omp_target_debug.c | 0 .../test/jit/empty_kernel.inc | 0 .../test/jit/empty_kernel_lvl1.c | 0 .../test/jit/empty_kernel_lvl2.c | 0 .../test/jit/type_punning.c | 0 .../test/libc/assert.c | 0 .../test/libc/fwrite.c | 0 .../test/libc/global_ctor_dtor.cpp | 0 .../test/libc/host_call.c | 0 .../test/libc/malloc.c | 0 .../libomptarget => offload}/test/libc/puts.c | 0 {openmp/libomptarget => offload}/test/lit.cfg | 0 .../test/lit.site.cfg.in | 0 .../test/mapping/alloc_fail.c | 0 .../mapping/array_section_implicit_capture.c | 0 .../mapping/array_section_use_device_ptr.c | 0 .../test/mapping/auto_zero_copy.cpp | 0 .../test/mapping/auto_zero_copy_apu.cpp | 0 .../test/mapping/auto_zero_copy_globals.cpp | 0 .../test/mapping/data_absent_at_exit.c | 0 .../test/mapping/data_member_ref.cpp | 0 .../test/mapping/declare_mapper_api.cpp | 0 .../declare_mapper_nested_default_mappers.cpp | 0 ...re_mapper_nested_default_mappers_array.cpp | 0 ...nested_default_mappers_array_subscript.cpp | 0 ...sted_default_mappers_complex_structure.cpp | 0 ...r_nested_default_mappers_ptr_subscript.cpp | 0 ...lare_mapper_nested_default_mappers_var.cpp | 0 .../mapping/declare_mapper_nested_mappers.cpp | 0 .../test/mapping/declare_mapper_target.cpp | 0 .../mapping/declare_mapper_target_data.cpp | 0 .../declare_mapper_target_data_enter_exit.cpp | 0 .../mapping/declare_mapper_target_update.cpp | 0 .../test/mapping/delete_inf_refcount.c | 0 .../test/mapping/device_ptr_update.c | 0 .../test/mapping/firstprivate_aligned.cpp | 0 .../test/mapping/has_device_addr.cpp | 0 .../test/mapping/implicit_device_ptr.c | 0 .../test/mapping/is_device_ptr.cpp | 0 .../test/mapping/lambda_by_value.cpp | 0 .../test/mapping/lambda_mapping.cpp | 0 .../test/mapping/low_alignment.c | 0 .../test/mapping/map_back_race.cpp | 0 .../ompx_hold/omp_target_disassociate_ptr.c | 0 .../test/mapping/ompx_hold/struct.c | 0 .../test/mapping/ompx_hold/target-data.c | 0 .../test/mapping/ompx_hold/target.c | 0 .../test/mapping/padding_not_mapped.c | 0 .../test/mapping/power_of_two_alignment.c | 0 .../test/mapping/pr38704.c | 0 .../test/mapping/prelock.cpp | 0 .../test/mapping/present/target.c | 0 .../mapping/present/target_array_extension.c | 0 .../test/mapping/present/target_data.c | 0 .../present/target_data_array_extension.c | 0 .../mapping/present/target_data_at_exit.c | 0 .../test/mapping/present/target_enter_data.c | 0 .../mapping/present/target_exit_data_delete.c | 0 .../present/target_exit_data_release.c | 0 .../test/mapping/present/target_update.c | 0 .../present/target_update_array_extension.c | 0 .../mapping/present/unified_shared_memory.c | 0 .../present/zero_length_array_section.c | 0 .../present/zero_length_array_section_exit.c | 0 .../test/mapping/private_mapping.c | 0 .../test/mapping/ptr_and_obj_motion.c | 0 .../test/mapping/reduction_implicit_map.cpp | 0 .../target_data_array_extension_at_exit.c | 0 .../target_derefence_array_pointrs.cpp | 0 .../test/mapping/target_has_device_addr.c | 0 .../mapping/target_implicit_partial_map.c | 0 .../mapping/target_map_for_member_data.cpp | 0 .../mapping/target_pointers_members_map.cpp | 0 .../mapping/target_update_array_extension.c | 0 .../test/mapping/target_use_device_addr.c | 0 .../test/mapping/target_uses_allocator.c | 0 .../mapping/target_wrong_use_device_addr.c | 0 .../test/offloading/assert.cpp | 0 .../offloading/atomic-compare-signedness.c | 0 .../test/offloading/back2back_distribute.c | 0 .../test/offloading/barrier_fence.c | 0 .../test/offloading/bug47654.cpp | 0 .../test/offloading/bug49021.cpp | 0 .../test/offloading/bug49334.cpp | 0 .../test/offloading/bug49779.cpp | 0 .../test/offloading/bug50022.cpp | 0 .../test/offloading/bug51781.c | 0 .../test/offloading/bug51982.c | 0 .../test/offloading/bug53727.cpp | 0 .../test/offloading/bug64959.c | 0 .../test/offloading/bug64959_compile_only.c | 0 .../test/offloading/bug74582.c | 0 .../test/offloading/complex_reduction.cpp | 0 .../test/offloading/ctor_dtor.cpp | 0 .../test/offloading/cuda_no_devices.c | 0 .../test/offloading/d2d_memcpy.c | 0 .../test/offloading/d2d_memcpy_sync.c | 0 .../test/offloading/default_thread_limit.c | 0 .../test/offloading/dynamic_module.c | 0 .../test/offloading/dynamic_module_load.c | 0 .../test/offloading/extern.c | 0 .../test/offloading/force-usm.cpp | 0 .../fortran/basic-target-parallel-do.f90 | 0 .../fortran/basic-target-parallel-region.f90 | 0 .../basic-target-region-1D-array-section.f90 | 0 .../basic-target-region-3D-array-section.f90 | 0 .../fortran/basic-target-region-3D-array.f90 | 0 .../test/offloading/fortran/basic_array.c | 0 .../fortran/basic_target_region.f90 | 0 .../offloading/fortran/constant-arr-index.f90 | 0 .../declare-target-vars-in-target-region.f90 | 0 ...double-target-call-with-declare-target.f90 | 0 ...ap-allocatable-array-section-1d-bounds.f90 | 0 ...ap-allocatable-array-section-3d-bounds.f90 | 0 .../target-map-allocatable-map-scopes.f90 | 0 .../target-map-enter-exit-allocatables.f90 | 0 .../fortran/target-map-enter-exit-array-2.f90 | 0 .../target-map-enter-exit-array-bounds.f90 | 0 .../fortran/target-map-enter-exit-array.f90 | 0 .../fortran/target-map-enter-exit-scalar.f90 | 0 .../target-map-pointer-scopes-enter-exit.f90 | 0 ...pointer-target-array-section-3d-bounds.f90 | 0 .../target-map-pointer-target-scopes.f90 | 0 .../fortran/target-nested-target-data.f90 | 0 .../fortran/target-parallel-do-collapse.f90 | 0 .../fortran/target-region-implicit-array.f90 | 0 .../fortran/target_map_common_block.f90 | 0 .../fortran/target_map_common_block1.f90 | 0 .../fortran/target_map_common_block2.f90 | 0 .../test/offloading/fortran/target_update.f90 | 0 .../generic_multiple_parallel_regions.c | 0 .../test/offloading/global_constructor.cpp | 0 .../test/offloading/host_as_target.c | 0 .../test/offloading/indirect_fp_mapping.c | 0 .../test/offloading/info.c | 0 .../test/offloading/interop.c | 0 .../test/offloading/lone_target_exit_data.c | 0 .../test/offloading/looptripcnt.c | 0 .../test/offloading/malloc.c | 0 .../test/offloading/malloc_parallel.c | 0 .../offloading/mandatory_but_no_devices.c | 0 .../test/offloading/memory_manager.cpp | 0 .../offloading/multiple_reductions_simple.c | 0 .../test/offloading/non_contiguous_update.cpp | 0 .../test/offloading/offloading_success.c | 0 .../test/offloading/offloading_success.cpp | 0 .../test/offloading/ompx_bare.c | 0 .../test/offloading/ompx_coords.c | 0 .../test/offloading/ompx_saxpy_mixed.c | 0 .../offloading/parallel_offloading_map.cpp | 0 .../parallel_target_teams_reduction.cpp | 0 .../parallel_target_teams_reduction_max.cpp | 0 .../parallel_target_teams_reduction_min.cpp | 0 .../test/offloading/requires.c | 0 .../test/offloading/runtime_init.c | 0 .../test/offloading/shared_lib_fp_mapping.c | 0 .../test/offloading/small_trip_count.c | 0 .../small_trip_count_thread_limit.cpp | 0 .../test/offloading/spmdization.c | 0 .../test/offloading/static_linking.c | 0 .../offloading/std_complex_arithmetic.cpp | 0 .../struct_mapping_with_pointers.cpp | 0 .../test/offloading/target-teams-atomic.c | 0 .../test/offloading/target-tile.c | 0 .../offloading/target_constexpr_mapping.cpp | 0 .../offloading/target_critical_region.cpp | 0 .../test/offloading/target_depend_nowait.cpp | 0 .../offloading/target_map_for_member_data.cpp | 0 .../test/offloading/target_nowait_target.cpp | 0 .../offloading/task_in_reduction_target.c | 0 .../offloading/taskloop_offload_nowait.cpp | 0 .../test/offloading/test_libc.cpp | 0 .../test/offloading/thread_limit.c | 0 .../test/offloading/thread_state_1.c | 0 .../test/offloading/thread_state_2.c | 0 .../test/offloading/weak.c | 0 .../test/offloading/workshare_chunk.c | 0 .../test/offloading/wtime.c | 0 .../test/ompt/callbacks.h | 0 .../test/ompt/register_both.h | 0 .../test/ompt/register_emi.h | 0 .../test/ompt/register_emi_map.h | 0 .../test/ompt/register_no_device_init.h | 0 .../test/ompt/register_non_emi.h | 0 .../test/ompt/register_non_emi_map.h | 0 .../test/ompt/register_wrong_return.h | 0 .../test/ompt/target_memcpy.c | 0 .../test/ompt/target_memcpy_emi.c | 0 .../test/ompt/veccopy.c | 0 .../test/ompt/veccopy_data.c | 0 .../test/ompt/veccopy_disallow_both.c | 0 .../test/ompt/veccopy_emi.c | 0 .../test/ompt/veccopy_emi_map.c | 0 .../test/ompt/veccopy_map.c | 0 .../test/ompt/veccopy_no_device_init.c | 0 .../test/ompt/veccopy_wrong_return.c | 0 .../test/unified_shared_memory/api.c | 0 .../unified_shared_memory/associate_ptr.c | 0 .../unified_shared_memory/close_enter_exit.c | 0 .../test/unified_shared_memory/close_manual.c | 0 .../test/unified_shared_memory/close_member.c | 0 .../unified_shared_memory/close_modifier.c | 0 .../unified_shared_memory/shared_update.c | 0 .../tools/CMakeLists.txt | 0 .../tools/deviceinfo/CMakeLists.txt | 0 .../tools/deviceinfo/llvm-omp-device-info.cpp | 0 .../tools/kernelreplay/CMakeLists.txt | 0 .../kernelreplay/llvm-omp-kernel-replay.cpp | 0 .../unittests/CMakeLists.txt | 0 .../unittests/Plugins/CMakeLists.txt | 0 .../unittests/Plugins/NextgenPluginsTest.cpp | 0 .../utils/generate_microtask_cases.py | 0 openmp/CMakeLists.txt | 29 +-- .../test/api/ompx_dump_mapping_tables.cpp | 35 --- openmp/runtime/src/CMakeLists.txt | 8 +- runtimes/CMakeLists.txt | 2 +- 353 files changed, 442 insertions(+), 73 deletions(-) rename {openmp/libomptarget => offload}/CMakeLists.txt (56%) rename {openmp/libomptarget => offload}/DeviceRTL/CMakeLists.txt (99%) rename {openmp/libomptarget => offload}/DeviceRTL/include/Allocator.h (100%) rename {openmp/libomptarget => offload}/DeviceRTL/include/Configuration.h (100%) rename {openmp/libomptarget => offload}/DeviceRTL/include/Debug.h (100%) rename {openmp/libomptarget => offload}/DeviceRTL/include/Interface.h (100%) rename {openmp/libomptarget => offload}/DeviceRTL/include/LibC.h (100%) rename {openmp/libomptarget => offload}/DeviceRTL/include/Mapping.h (100%) rename {openmp/libomptarget => offload}/DeviceRTL/include/State.h (100%) rename {openmp/libomptarget => offload}/DeviceRTL/include/Synchronization.h (100%) rename {openmp/libomptarget => offload}/DeviceRTL/include/Types.h (100%) rename {openmp/libomptarget => offload}/DeviceRTL/include/Utils.h (100%) rename {openmp/libomptarget => offload}/DeviceRTL/include/generated_microtask_cases.gen (100%) rename {openmp/libomptarget => offload}/DeviceRTL/src/Allocator.cpp (100%) rename {openmp/libomptarget => offload}/DeviceRTL/src/Configuration.cpp (100%) rename {openmp/libomptarget => offload}/DeviceRTL/src/Debug.cpp (100%) rename {openmp/libomptarget => offload}/DeviceRTL/src/Kernel.cpp (100%) rename {openmp/libomptarget => offload}/DeviceRTL/src/LibC.cpp (100%) rename {openmp/libomptarget => offload}/DeviceRTL/src/Mapping.cpp (100%) rename {openmp/libomptarget => offload}/DeviceRTL/src/Misc.cpp (100%) rename {openmp/libomptarget => offload}/DeviceRTL/src/Parallelism.cpp (100%) rename {openmp/libomptarget => offload}/DeviceRTL/src/Reduction.cpp (100%) rename {openmp/libomptarget => offload}/DeviceRTL/src/State.cpp (100%) rename {openmp/libomptarget => offload}/DeviceRTL/src/Stub.cpp (100%) rename {openmp/libomptarget => offload}/DeviceRTL/src/Synchronization.cpp (100%) rename {openmp/libomptarget => offload}/DeviceRTL/src/Tasking.cpp (100%) rename {openmp/libomptarget => offload}/DeviceRTL/src/Utils.cpp (100%) rename {openmp/libomptarget => offload}/DeviceRTL/src/Workshare.cpp (100%) rename {openmp/libomptarget => offload}/DeviceRTL/src/exports (100%) rename {openmp/libomptarget => offload}/README.txt (100%) rename {openmp/libomptarget => offload}/cmake/Modules/LibomptargetGetDependencies.cmake (100%) rename {openmp/libomptarget => offload}/cmake/Modules/LibomptargetUtils.cmake (100%) create mode 100644 offload/cmake/OpenMPTesting.cmake rename {openmp/libomptarget => offload}/docs/declare_target_indirect.md (100%) rename {openmp/libomptarget => offload}/include/DeviceImage.h (100%) rename {openmp/libomptarget => offload}/include/ExclusiveAccess.h (100%) rename {openmp/libomptarget => offload}/include/OffloadEntry.h (100%) rename {openmp/libomptarget => offload}/include/OffloadPolicy.h (100%) rename {openmp/libomptarget => offload}/include/OpenMP/InternalTypes.h (100%) rename {openmp/libomptarget => offload}/include/OpenMP/InteropAPI.h (100%) rename {openmp/libomptarget => offload}/include/OpenMP/Mapping.h (100%) rename {openmp/libomptarget => offload}/include/OpenMP/OMPT/Callback.h (100%) rename {openmp/libomptarget => offload}/include/OpenMP/OMPT/Connector.h (100%) rename {openmp/libomptarget => offload}/include/OpenMP/OMPT/Interface.h (100%) rename {openmp/libomptarget => offload}/include/OpenMP/omp.h (100%) rename {openmp/libomptarget => offload}/include/PluginManager.h (100%) rename {openmp/libomptarget => offload}/include/Shared/APITypes.h (100%) rename {openmp/libomptarget => offload}/include/Shared/Debug.h (100%) rename {openmp/libomptarget => offload}/include/Shared/Environment.h (100%) rename {openmp/libomptarget => offload}/include/Shared/EnvironmentVar.h (100%) rename {openmp/libomptarget => offload}/include/Shared/PluginAPI.h (100%) rename {openmp/libomptarget => offload}/include/Shared/PluginAPI.inc (100%) rename {openmp/libomptarget => offload}/include/Shared/Profile.h (100%) rename {openmp/libomptarget => offload}/include/Shared/Requirements.h (100%) rename {openmp/libomptarget => offload}/include/Shared/SourceInfo.h (100%) rename {openmp/libomptarget => offload}/include/Shared/Utils.h (100%) rename {openmp/libomptarget => offload}/include/Utils/ExponentialBackoff.h (100%) rename {openmp/libomptarget => offload}/include/device.h (100%) rename {openmp/libomptarget => offload}/include/omptarget.h (100%) rename {openmp/libomptarget => offload}/include/rtl.h (100%) rename {openmp/libomptarget => offload}/plugins-nextgen/CMakeLists.txt (100%) rename {openmp/libomptarget => offload}/plugins-nextgen/amdgpu/CMakeLists.txt (97%) rename {openmp/libomptarget => offload}/plugins-nextgen/amdgpu/dynamic_hsa/hsa.cpp (100%) rename {openmp/libomptarget => offload}/plugins-nextgen/amdgpu/dynamic_hsa/hsa.h (100%) rename {openmp/libomptarget => offload}/plugins-nextgen/amdgpu/dynamic_hsa/hsa_ext_amd.h (100%) rename {openmp/libomptarget => offload}/plugins-nextgen/amdgpu/src/rtl.cpp (100%) rename {openmp/libomptarget => offload}/plugins-nextgen/amdgpu/utils/UtilitiesRTL.h (100%) rename {openmp/libomptarget => offload}/plugins-nextgen/common/CMakeLists.txt (100%) rename {openmp/libomptarget => offload}/plugins-nextgen/common/OMPT/OmptCallback.cpp (100%) rename {openmp/libomptarget => offload}/plugins-nextgen/common/include/DLWrap.h (100%) rename {openmp/libomptarget => offload}/plugins-nextgen/common/include/GlobalHandler.h (100%) rename {openmp/libomptarget => offload}/plugins-nextgen/common/include/JIT.h (100%) rename {openmp/libomptarget => offload}/plugins-nextgen/common/include/MemoryManager.h (100%) rename {openmp/libomptarget => offload}/plugins-nextgen/common/include/PluginInterface.h (100%) rename {openmp/libomptarget => offload}/plugins-nextgen/common/include/RPC.h (100%) rename {openmp/libomptarget => offload}/plugins-nextgen/common/include/Utils/ELF.h (100%) rename {openmp/libomptarget => offload}/plugins-nextgen/common/src/GlobalHandler.cpp (100%) rename {openmp/libomptarget => offload}/plugins-nextgen/common/src/JIT.cpp (100%) rename {openmp/libomptarget => offload}/plugins-nextgen/common/src/PluginInterface.cpp (100%) rename {openmp/libomptarget => offload}/plugins-nextgen/common/src/RPC.cpp (100%) rename {openmp/libomptarget => offload}/plugins-nextgen/common/src/Utils/ELF.cpp (100%) rename {openmp/libomptarget => offload}/plugins-nextgen/cuda/CMakeLists.txt (96%) rename {openmp/libomptarget => offload}/plugins-nextgen/cuda/dynamic_cuda/cuda.cpp (100%) rename {openmp/libomptarget => offload}/plugins-nextgen/cuda/dynamic_cuda/cuda.h (100%) rename {openmp/libomptarget => offload}/plugins-nextgen/cuda/src/rtl.cpp (100%) rename {openmp/libomptarget => offload}/plugins-nextgen/exports (100%) rename {openmp/libomptarget => offload}/plugins-nextgen/host/CMakeLists.txt (98%) rename {openmp/libomptarget => offload}/plugins-nextgen/host/dynamic_ffi/ffi.cpp (100%) rename {openmp/libomptarget => offload}/plugins-nextgen/host/dynamic_ffi/ffi.h (100%) rename {openmp/libomptarget => offload}/plugins-nextgen/host/src/rtl.cpp (100%) rename {openmp/libomptarget => offload}/src/CMakeLists.txt (95%) rename {openmp/libomptarget => offload}/src/DeviceImage.cpp (100%) rename {openmp/libomptarget => offload}/src/LegacyAPI.cpp (100%) rename {openmp/libomptarget => offload}/src/OffloadRTL.cpp (100%) rename {openmp/libomptarget => offload}/src/OpenMP/API.cpp (100%) rename {openmp/libomptarget => offload}/src/OpenMP/InteropAPI.cpp (100%) rename {openmp/libomptarget => offload}/src/OpenMP/Mapping.cpp (100%) rename {openmp/libomptarget => offload}/src/OpenMP/OMPT/Callback.cpp (100%) rename {openmp/libomptarget => offload}/src/PluginManager.cpp (100%) rename {openmp/libomptarget => offload}/src/device.cpp (100%) rename {openmp/libomptarget => offload}/src/exports (100%) rename {openmp/libomptarget => offload}/src/interface.cpp (100%) rename {openmp/libomptarget => offload}/src/omptarget.cpp (100%) rename {openmp/libomptarget => offload}/src/private.h (100%) rename {openmp/libomptarget => offload}/test/CMakeLists.txt (78%) rename {openmp/libomptarget => offload}/test/Inputs/basic_array.f90 (100%) rename {openmp/libomptarget => offload}/test/Inputs/declare_indirect_func.c (100%) rename {openmp/libomptarget => offload}/test/api/assert.c (100%) rename {openmp/libomptarget => offload}/test/api/is_initial_device.c (100%) rename {openmp/libomptarget => offload}/test/api/omp_device_managed_memory.c (100%) rename {openmp/libomptarget => offload}/test/api/omp_device_managed_memory_alloc.c (100%) rename {openmp/libomptarget => offload}/test/api/omp_device_memory.c (100%) rename {openmp/libomptarget => offload}/test/api/omp_dynamic_shared_memory.c (100%) rename {openmp/libomptarget => offload}/test/api/omp_dynamic_shared_memory_amdgpu.c (100%) rename {openmp/libomptarget => offload}/test/api/omp_dynamic_shared_memory_mixed.inc (100%) rename {openmp/libomptarget => offload}/test/api/omp_dynamic_shared_memory_mixed_amdgpu.c (100%) rename {openmp/libomptarget => offload}/test/api/omp_dynamic_shared_memory_mixed_nvptx.c (100%) rename {openmp/libomptarget => offload}/test/api/omp_env_vars.c (100%) rename {openmp/libomptarget => offload}/test/api/omp_get_device_num.c (100%) rename {openmp/libomptarget => offload}/test/api/omp_get_mapped_ptr.c (100%) rename {openmp/libomptarget => offload}/test/api/omp_get_num_devices.c (100%) rename {openmp/libomptarget => offload}/test/api/omp_get_num_devices_with_empty_target.c (100%) rename {openmp/libomptarget => offload}/test/api/omp_get_num_procs.c (100%) rename {openmp/libomptarget => offload}/test/api/omp_host_pinned_memory.c (100%) rename {openmp/libomptarget => offload}/test/api/omp_host_pinned_memory_alloc.c (100%) rename {openmp/libomptarget => offload}/test/api/omp_indirect_call.c (100%) rename {openmp/libomptarget => offload}/test/api/omp_target_memcpy_async1.c (100%) rename {openmp/libomptarget => offload}/test/api/omp_target_memcpy_async2.c (100%) rename {openmp/libomptarget => offload}/test/api/omp_target_memcpy_rect_async1.c (100%) rename {openmp/libomptarget => offload}/test/api/omp_target_memcpy_rect_async2.c (100%) rename {openmp/libomptarget => offload}/test/api/omp_target_memset.c (100%) rename {openmp/libomptarget => offload}/test/api/ompx_3d.c (100%) rename {openmp/libomptarget => offload}/test/api/ompx_3d.cpp (100%) rename {openmp/libomptarget => offload}/test/api/ompx_sync.c (100%) rename {openmp/libomptarget => offload}/test/api/ompx_sync.cpp (100%) rename {openmp/libomptarget => offload}/test/env/base_ptr_ref_count.c (100%) rename {openmp/libomptarget => offload}/test/env/omp_target_debug.c (100%) rename {openmp/libomptarget => offload}/test/jit/empty_kernel.inc (100%) rename {openmp/libomptarget => offload}/test/jit/empty_kernel_lvl1.c (100%) rename {openmp/libomptarget => offload}/test/jit/empty_kernel_lvl2.c (100%) rename {openmp/libomptarget => offload}/test/jit/type_punning.c (100%) rename {openmp/libomptarget => offload}/test/libc/assert.c (100%) rename {openmp/libomptarget => offload}/test/libc/fwrite.c (100%) rename {openmp/libomptarget => offload}/test/libc/global_ctor_dtor.cpp (100%) rename {openmp/libomptarget => offload}/test/libc/host_call.c (100%) rename {openmp/libomptarget => offload}/test/libc/malloc.c (100%) rename {openmp/libomptarget => offload}/test/libc/puts.c (100%) rename {openmp/libomptarget => offload}/test/lit.cfg (100%) rename {openmp/libomptarget => offload}/test/lit.site.cfg.in (100%) rename {openmp/libomptarget => offload}/test/mapping/alloc_fail.c (100%) rename {openmp/libomptarget => offload}/test/mapping/array_section_implicit_capture.c (100%) rename {openmp/libomptarget => offload}/test/mapping/array_section_use_device_ptr.c (100%) rename {openmp/libomptarget => offload}/test/mapping/auto_zero_copy.cpp (100%) rename {openmp/libomptarget => offload}/test/mapping/auto_zero_copy_apu.cpp (100%) rename {openmp/libomptarget => offload}/test/mapping/auto_zero_copy_globals.cpp (100%) rename {openmp/libomptarget => offload}/test/mapping/data_absent_at_exit.c (100%) rename {openmp/libomptarget => offload}/test/mapping/data_member_ref.cpp (100%) rename {openmp/libomptarget => offload}/test/mapping/declare_mapper_api.cpp (100%) rename {openmp/libomptarget => offload}/test/mapping/declare_mapper_nested_default_mappers.cpp (100%) rename {openmp/libomptarget => offload}/test/mapping/declare_mapper_nested_default_mappers_array.cpp (100%) rename {openmp/libomptarget => offload}/test/mapping/declare_mapper_nested_default_mappers_array_subscript.cpp (100%) rename {openmp/libomptarget => offload}/test/mapping/declare_mapper_nested_default_mappers_complex_structure.cpp (100%) rename {openmp/libomptarget => offload}/test/mapping/declare_mapper_nested_default_mappers_ptr_subscript.cpp (100%) rename {openmp/libomptarget => offload}/test/mapping/declare_mapper_nested_default_mappers_var.cpp (100%) rename {openmp/libomptarget => offload}/test/mapping/declare_mapper_nested_mappers.cpp (100%) rename {openmp/libomptarget => offload}/test/mapping/declare_mapper_target.cpp (100%) rename {openmp/libomptarget => offload}/test/mapping/declare_mapper_target_data.cpp (100%) rename {openmp/libomptarget => offload}/test/mapping/declare_mapper_target_data_enter_exit.cpp (100%) rename {openmp/libomptarget => offload}/test/mapping/declare_mapper_target_update.cpp (100%) rename {openmp/libomptarget => offload}/test/mapping/delete_inf_refcount.c (100%) rename {openmp/libomptarget => offload}/test/mapping/device_ptr_update.c (100%) rename {openmp/libomptarget => offload}/test/mapping/firstprivate_aligned.cpp (100%) rename {openmp/libomptarget => offload}/test/mapping/has_device_addr.cpp (100%) rename {openmp/libomptarget => offload}/test/mapping/implicit_device_ptr.c (100%) rename {openmp/libomptarget => offload}/test/mapping/is_device_ptr.cpp (100%) rename {openmp/libomptarget => offload}/test/mapping/lambda_by_value.cpp (100%) rename {openmp/libomptarget => offload}/test/mapping/lambda_mapping.cpp (100%) rename {openmp/libomptarget => offload}/test/mapping/low_alignment.c (100%) rename {openmp/libomptarget => offload}/test/mapping/map_back_race.cpp (100%) rename {openmp/libomptarget => offload}/test/mapping/ompx_hold/omp_target_disassociate_ptr.c (100%) rename {openmp/libomptarget => offload}/test/mapping/ompx_hold/struct.c (100%) rename {openmp/libomptarget => offload}/test/mapping/ompx_hold/target-data.c (100%) rename {openmp/libomptarget => offload}/test/mapping/ompx_hold/target.c (100%) rename {openmp/libomptarget => offload}/test/mapping/padding_not_mapped.c (100%) rename {openmp/libomptarget => offload}/test/mapping/power_of_two_alignment.c (100%) rename {openmp/libomptarget => offload}/test/mapping/pr38704.c (100%) rename {openmp/libomptarget => offload}/test/mapping/prelock.cpp (100%) rename {openmp/libomptarget => offload}/test/mapping/present/target.c (100%) rename {openmp/libomptarget => offload}/test/mapping/present/target_array_extension.c (100%) rename {openmp/libomptarget => offload}/test/mapping/present/target_data.c (100%) rename {openmp/libomptarget => offload}/test/mapping/present/target_data_array_extension.c (100%) rename {openmp/libomptarget => offload}/test/mapping/present/target_data_at_exit.c (100%) rename {openmp/libomptarget => offload}/test/mapping/present/target_enter_data.c (100%) rename {openmp/libomptarget => offload}/test/mapping/present/target_exit_data_delete.c (100%) rename {openmp/libomptarget => offload}/test/mapping/present/target_exit_data_release.c (100%) rename {openmp/libomptarget => offload}/test/mapping/present/target_update.c (100%) rename {openmp/libomptarget => offload}/test/mapping/present/target_update_array_extension.c (100%) rename {openmp/libomptarget => offload}/test/mapping/present/unified_shared_memory.c (100%) rename {openmp/libomptarget => offload}/test/mapping/present/zero_length_array_section.c (100%) rename {openmp/libomptarget => offload}/test/mapping/present/zero_length_array_section_exit.c (100%) rename {openmp/libomptarget => offload}/test/mapping/private_mapping.c (100%) rename {openmp/libomptarget => offload}/test/mapping/ptr_and_obj_motion.c (100%) rename {openmp/libomptarget => offload}/test/mapping/reduction_implicit_map.cpp (100%) rename {openmp/libomptarget => offload}/test/mapping/target_data_array_extension_at_exit.c (100%) rename {openmp/libomptarget => offload}/test/mapping/target_derefence_array_pointrs.cpp (100%) rename {openmp/libomptarget => offload}/test/mapping/target_has_device_addr.c (100%) rename {openmp/libomptarget => offload}/test/mapping/target_implicit_partial_map.c (100%) rename {openmp/libomptarget => offload}/test/mapping/target_map_for_member_data.cpp (100%) rename {openmp/libomptarget => offload}/test/mapping/target_pointers_members_map.cpp (100%) rename {openmp/libomptarget => offload}/test/mapping/target_update_array_extension.c (100%) rename {openmp/libomptarget => offload}/test/mapping/target_use_device_addr.c (100%) rename {openmp/libomptarget => offload}/test/mapping/target_uses_allocator.c (100%) rename {openmp/libomptarget => offload}/test/mapping/target_wrong_use_device_addr.c (100%) rename {openmp/libomptarget => offload}/test/offloading/assert.cpp (100%) rename {openmp/libomptarget => offload}/test/offloading/atomic-compare-signedness.c (100%) rename {openmp/libomptarget => offload}/test/offloading/back2back_distribute.c (100%) rename {openmp/libomptarget => offload}/test/offloading/barrier_fence.c (100%) rename {openmp/libomptarget => offload}/test/offloading/bug47654.cpp (100%) rename {openmp/libomptarget => offload}/test/offloading/bug49021.cpp (100%) rename {openmp/libomptarget => offload}/test/offloading/bug49334.cpp (100%) rename {openmp/libomptarget => offload}/test/offloading/bug49779.cpp (100%) rename {openmp/libomptarget => offload}/test/offloading/bug50022.cpp (100%) rename {openmp/libomptarget => offload}/test/offloading/bug51781.c (100%) rename {openmp/libomptarget => offload}/test/offloading/bug51982.c (100%) rename {openmp/libomptarget => offload}/test/offloading/bug53727.cpp (100%) rename {openmp/libomptarget => offload}/test/offloading/bug64959.c (100%) rename {openmp/libomptarget => offload}/test/offloading/bug64959_compile_only.c (100%) rename {openmp/libomptarget => offload}/test/offloading/bug74582.c (100%) rename {openmp/libomptarget => offload}/test/offloading/complex_reduction.cpp (100%) rename {openmp/libomptarget => offload}/test/offloading/ctor_dtor.cpp (100%) rename {openmp/libomptarget => offload}/test/offloading/cuda_no_devices.c (100%) rename {openmp/libomptarget => offload}/test/offloading/d2d_memcpy.c (100%) rename {openmp/libomptarget => offload}/test/offloading/d2d_memcpy_sync.c (100%) rename {openmp/libomptarget => offload}/test/offloading/default_thread_limit.c (100%) rename {openmp/libomptarget => offload}/test/offloading/dynamic_module.c (100%) rename {openmp/libomptarget => offload}/test/offloading/dynamic_module_load.c (100%) rename {openmp/libomptarget => offload}/test/offloading/extern.c (100%) rename {openmp/libomptarget => offload}/test/offloading/force-usm.cpp (100%) rename {openmp/libomptarget => offload}/test/offloading/fortran/basic-target-parallel-do.f90 (100%) rename {openmp/libomptarget => offload}/test/offloading/fortran/basic-target-parallel-region.f90 (100%) rename {openmp/libomptarget => offload}/test/offloading/fortran/basic-target-region-1D-array-section.f90 (100%) rename {openmp/libomptarget => offload}/test/offloading/fortran/basic-target-region-3D-array-section.f90 (100%) rename {openmp/libomptarget => offload}/test/offloading/fortran/basic-target-region-3D-array.f90 (100%) rename {openmp/libomptarget => offload}/test/offloading/fortran/basic_array.c (100%) rename {openmp/libomptarget => offload}/test/offloading/fortran/basic_target_region.f90 (100%) rename {openmp/libomptarget => offload}/test/offloading/fortran/constant-arr-index.f90 (100%) rename {openmp/libomptarget => offload}/test/offloading/fortran/declare-target-vars-in-target-region.f90 (100%) rename {openmp/libomptarget => offload}/test/offloading/fortran/double-target-call-with-declare-target.f90 (100%) rename {openmp/libomptarget => offload}/test/offloading/fortran/target-map-allocatable-array-section-1d-bounds.f90 (100%) rename {openmp/libomptarget => offload}/test/offloading/fortran/target-map-allocatable-array-section-3d-bounds.f90 (100%) rename {openmp/libomptarget => offload}/test/offloading/fortran/target-map-allocatable-map-scopes.f90 (100%) rename {openmp/libomptarget => offload}/test/offloading/fortran/target-map-enter-exit-allocatables.f90 (100%) rename {openmp/libomptarget => offload}/test/offloading/fortran/target-map-enter-exit-array-2.f90 (100%) rename {openmp/libomptarget => offload}/test/offloading/fortran/target-map-enter-exit-array-bounds.f90 (100%) rename {openmp/libomptarget => offload}/test/offloading/fortran/target-map-enter-exit-array.f90 (100%) rename {openmp/libomptarget => offload}/test/offloading/fortran/target-map-enter-exit-scalar.f90 (100%) rename {openmp/libomptarget => offload}/test/offloading/fortran/target-map-pointer-scopes-enter-exit.f90 (100%) rename {openmp/libomptarget => offload}/test/offloading/fortran/target-map-pointer-target-array-section-3d-bounds.f90 (100%) rename {openmp/libomptarget => offload}/test/offloading/fortran/target-map-pointer-target-scopes.f90 (100%) rename {openmp/libomptarget => offload}/test/offloading/fortran/target-nested-target-data.f90 (100%) rename {openmp/libomptarget => offload}/test/offloading/fortran/target-parallel-do-collapse.f90 (100%) rename {openmp/libomptarget => offload}/test/offloading/fortran/target-region-implicit-array.f90 (100%) rename {openmp/libomptarget => offload}/test/offloading/fortran/target_map_common_block.f90 (100%) rename {openmp/libomptarget => offload}/test/offloading/fortran/target_map_common_block1.f90 (100%) rename {openmp/libomptarget => offload}/test/offloading/fortran/target_map_common_block2.f90 (100%) rename {openmp/libomptarget => offload}/test/offloading/fortran/target_update.f90 (100%) rename {openmp/libomptarget => offload}/test/offloading/generic_multiple_parallel_regions.c (100%) rename {openmp/libomptarget => offload}/test/offloading/global_constructor.cpp (100%) rename {openmp/libomptarget => offload}/test/offloading/host_as_target.c (100%) rename {openmp/libomptarget => offload}/test/offloading/indirect_fp_mapping.c (100%) rename {openmp/libomptarget => offload}/test/offloading/info.c (100%) rename {openmp/libomptarget => offload}/test/offloading/interop.c (100%) rename {openmp/libomptarget => offload}/test/offloading/lone_target_exit_data.c (100%) rename {openmp/libomptarget => offload}/test/offloading/looptripcnt.c (100%) rename {openmp/libomptarget => offload}/test/offloading/malloc.c (100%) rename {openmp/libomptarget => offload}/test/offloading/malloc_parallel.c (100%) rename {openmp/libomptarget => offload}/test/offloading/mandatory_but_no_devices.c (100%) rename {openmp/libomptarget => offload}/test/offloading/memory_manager.cpp (100%) rename {openmp/libomptarget => offload}/test/offloading/multiple_reductions_simple.c (100%) rename {openmp/libomptarget => offload}/test/offloading/non_contiguous_update.cpp (100%) rename {openmp/libomptarget => offload}/test/offloading/offloading_success.c (100%) rename {openmp/libomptarget => offload}/test/offloading/offloading_success.cpp (100%) rename {openmp/libomptarget => offload}/test/offloading/ompx_bare.c (100%) rename {openmp/libomptarget => offload}/test/offloading/ompx_coords.c (100%) rename {openmp/libomptarget => offload}/test/offloading/ompx_saxpy_mixed.c (100%) rename {openmp/libomptarget => offload}/test/offloading/parallel_offloading_map.cpp (100%) rename {openmp/libomptarget => offload}/test/offloading/parallel_target_teams_reduction.cpp (100%) rename {openmp/libomptarget => offload}/test/offloading/parallel_target_teams_reduction_max.cpp (100%) rename {openmp/libomptarget => offload}/test/offloading/parallel_target_teams_reduction_min.cpp (100%) rename {openmp/libomptarget => offload}/test/offloading/requires.c (100%) rename {openmp/libomptarget => offload}/test/offloading/runtime_init.c (100%) rename {openmp/libomptarget => offload}/test/offloading/shared_lib_fp_mapping.c (100%) rename {openmp/libomptarget => offload}/test/offloading/small_trip_count.c (100%) rename {openmp/libomptarget => offload}/test/offloading/small_trip_count_thread_limit.cpp (100%) rename {openmp/libomptarget => offload}/test/offloading/spmdization.c (100%) rename {openmp/libomptarget => offload}/test/offloading/static_linking.c (100%) rename {openmp/libomptarget => offload}/test/offloading/std_complex_arithmetic.cpp (100%) rename {openmp/libomptarget => offload}/test/offloading/struct_mapping_with_pointers.cpp (100%) rename {openmp/libomptarget => offload}/test/offloading/target-teams-atomic.c (100%) rename {openmp/libomptarget => offload}/test/offloading/target-tile.c (100%) rename {openmp/libomptarget => offload}/test/offloading/target_constexpr_mapping.cpp (100%) rename {openmp/libomptarget => offload}/test/offloading/target_critical_region.cpp (100%) rename {openmp/libomptarget => offload}/test/offloading/target_depend_nowait.cpp (100%) rename {openmp/libomptarget => offload}/test/offloading/target_map_for_member_data.cpp (100%) rename {openmp/libomptarget => offload}/test/offloading/target_nowait_target.cpp (100%) rename {openmp/libomptarget => offload}/test/offloading/task_in_reduction_target.c (100%) rename {openmp/libomptarget => offload}/test/offloading/taskloop_offload_nowait.cpp (100%) rename {openmp/libomptarget => offload}/test/offloading/test_libc.cpp (100%) rename {openmp/libomptarget => offload}/test/offloading/thread_limit.c (100%) rename {openmp/libomptarget => offload}/test/offloading/thread_state_1.c (100%) rename {openmp/libomptarget => offload}/test/offloading/thread_state_2.c (100%) rename {openmp/libomptarget => offload}/test/offloading/weak.c (100%) rename {openmp/libomptarget => offload}/test/offloading/workshare_chunk.c (100%) rename {openmp/libomptarget => offload}/test/offloading/wtime.c (100%) rename {openmp/libomptarget => offload}/test/ompt/callbacks.h (100%) rename {openmp/libomptarget => offload}/test/ompt/register_both.h (100%) rename {openmp/libomptarget => offload}/test/ompt/register_emi.h (100%) rename {openmp/libomptarget => offload}/test/ompt/register_emi_map.h (100%) rename {openmp/libomptarget => offload}/test/ompt/register_no_device_init.h (100%) rename {openmp/libomptarget => offload}/test/ompt/register_non_emi.h (100%) rename {openmp/libomptarget => offload}/test/ompt/register_non_emi_map.h (100%) rename {openmp/libomptarget => offload}/test/ompt/register_wrong_return.h (100%) rename {openmp/libomptarget => offload}/test/ompt/target_memcpy.c (100%) rename {openmp/libomptarget => offload}/test/ompt/target_memcpy_emi.c (100%) rename {openmp/libomptarget => offload}/test/ompt/veccopy.c (100%) rename {openmp/libomptarget => offload}/test/ompt/veccopy_data.c (100%) rename {openmp/libomptarget => offload}/test/ompt/veccopy_disallow_both.c (100%) rename {openmp/libomptarget => offload}/test/ompt/veccopy_emi.c (100%) rename {openmp/libomptarget => offload}/test/ompt/veccopy_emi_map.c (100%) rename {openmp/libomptarget => offload}/test/ompt/veccopy_map.c (100%) rename {openmp/libomptarget => offload}/test/ompt/veccopy_no_device_init.c (100%) rename {openmp/libomptarget => offload}/test/ompt/veccopy_wrong_return.c (100%) rename {openmp/libomptarget => offload}/test/unified_shared_memory/api.c (100%) rename {openmp/libomptarget => offload}/test/unified_shared_memory/associate_ptr.c (100%) rename {openmp/libomptarget => offload}/test/unified_shared_memory/close_enter_exit.c (100%) rename {openmp/libomptarget => offload}/test/unified_shared_memory/close_manual.c (100%) rename {openmp/libomptarget => offload}/test/unified_shared_memory/close_member.c (100%) rename {openmp/libomptarget => offload}/test/unified_shared_memory/close_modifier.c (100%) rename {openmp/libomptarget => offload}/test/unified_shared_memory/shared_update.c (100%) rename {openmp/libomptarget => offload}/tools/CMakeLists.txt (100%) rename {openmp/libomptarget => offload}/tools/deviceinfo/CMakeLists.txt (100%) rename {openmp/libomptarget => offload}/tools/deviceinfo/llvm-omp-device-info.cpp (100%) rename {openmp/libomptarget => offload}/tools/kernelreplay/CMakeLists.txt (100%) rename {openmp/libomptarget => offload}/tools/kernelreplay/llvm-omp-kernel-replay.cpp (100%) rename {openmp/libomptarget => offload}/unittests/CMakeLists.txt (100%) rename {openmp/libomptarget => offload}/unittests/Plugins/CMakeLists.txt (100%) rename {openmp/libomptarget => offload}/unittests/Plugins/NextgenPluginsTest.cpp (100%) rename {openmp/libomptarget => offload}/utils/generate_microtask_cases.py (100%) delete mode 100644 openmp/libomptarget/test/api/ompx_dump_mapping_tables.cpp diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt index d511376e18ba..43181af3bc19 100644 --- a/llvm/CMakeLists.txt +++ b/llvm/CMakeLists.txt @@ -147,7 +147,7 @@ endif() # As we migrate runtimes to using the bootstrapping build, the set of default runtimes # should grow as we remove those runtimes from LLVM_ENABLE_PROJECTS above. set(LLVM_DEFAULT_RUNTIMES "libcxx;libcxxabi;libunwind") -set(LLVM_SUPPORTED_RUNTIMES "libc;libunwind;libcxxabi;pstl;libcxx;compiler-rt;openmp;llvm-libgcc") +set(LLVM_SUPPORTED_RUNTIMES "libc;libunwind;libcxxabi;pstl;libcxx;compiler-rt;openmp;llvm-libgcc;offload") set(LLVM_ENABLE_RUNTIMES "" CACHE STRING "Semicolon-separated list of runtimes to build, or \"all\" (${LLVM_DEFAULT_RUNTIMES}). Supported runtimes are ${LLVM_SUPPORTED_RUNTIMES}.") if(LLVM_ENABLE_RUNTIMES STREQUAL "all") diff --git a/openmp/libomptarget/CMakeLists.txt b/offload/CMakeLists.txt similarity index 56% rename from openmp/libomptarget/CMakeLists.txt rename to offload/CMakeLists.txt index 531198fae016..b23ffdcbd5aa 100644 --- a/openmp/libomptarget/CMakeLists.txt +++ b/offload/CMakeLists.txt @@ -10,12 +10,106 @@ # ##===----------------------------------------------------------------------===## -if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}") - message(FATAL_ERROR "Direct configuration not supported, please use parent directory!") +cmake_minimum_required(VERSION 3.20.0) + +if ("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}") + set(OPENMP_STANDALONE_BUILD TRUE) + project(offload C CXX ASM) +endif() + +set(ENABLE_LIBOMPTARGET ON) +# Currently libomptarget cannot be compiled on Windows or MacOS X. +# Since the device plugins are only supported on Linux anyway, +# there is no point in trying to compile libomptarget on other OSes. +# 32-bit systems are not supported either. +if (APPLE OR WIN32 OR NOT "cxx_std_17" IN_LIST CMAKE_CXX_COMPILE_FEATURES OR NOT CMAKE_SIZEOF_VOID_P EQUAL 8) + set(ENABLE_LIBOMPTARGET OFF) endif() -# Add cmake directory to search for custom cmake functions. -set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules ${CMAKE_MODULE_PATH}) +option(OPENMP_ENABLE_LIBOMPTARGET "Enable building libomptarget for offloading." + ${ENABLE_LIBOMPTARGET}) +if (OPENMP_ENABLE_LIBOMPTARGET) + # Check that the library can actually be built. + if (APPLE OR WIN32) + message(FATAL_ERROR "libomptarget cannot be built on Windows and MacOS X!") + elseif (NOT "cxx_std_17" IN_LIST CMAKE_CXX_COMPILE_FEATURES) + message(FATAL_ERROR "Host compiler must support C++17 to build libomptarget!") + elseif (NOT CMAKE_SIZEOF_VOID_P EQUAL 8) + message(FATAL_ERROR "libomptarget on 32-bit systems are not supported!") + endif() +endif() + +# TODO: Leftover from the move, could probably be just LLVM_LIBDIR_SUFFIX everywhere. +set(OFFLOAD_INSTALL_LIBDIR "lib${LLVM_LIBDIR_SUFFIX}") + +set(LLVM_COMMON_CMAKE_UTILS ${CMAKE_CURRENT_SOURCE_DIR}/../cmake) + +# Add path for custom modules +list(INSERT CMAKE_MODULE_PATH 0 + "${CMAKE_CURRENT_SOURCE_DIR}/cmake" + "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules" + "${LLVM_COMMON_CMAKE_UTILS}/Modules" + ) + +if (OPENMP_STANDALONE_BUILD) + # CMAKE_BUILD_TYPE was not set, default to Release. + if (NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Release) + endif() + + # Group common settings. + set(OPENMP_ENABLE_WERROR FALSE CACHE BOOL + "Enable -Werror flags to turn warnings into errors for supporting compilers.") + set(OPENMP_LIBDIR_SUFFIX "" CACHE STRING + "Suffix of lib installation directory, e.g. 64 => lib64") + # Do not use OPENMP_LIBDIR_SUFFIX directly, use OPENMP_INSTALL_LIBDIR. + set(OPENMP_INSTALL_LIBDIR "lib${OPENMP_LIBDIR_SUFFIX}") + + # Group test settings. + set(OPENMP_TEST_C_COMPILER ${CMAKE_C_COMPILER} CACHE STRING + "C compiler to use for testing OpenMP runtime libraries.") + set(OPENMP_TEST_CXX_COMPILER ${CMAKE_CXX_COMPILER} CACHE STRING + "C++ compiler to use for testing OpenMP runtime libraries.") + set(OPENMP_TEST_Fortran_COMPILER ${CMAKE_Fortran_COMPILER} CACHE STRING + "FORTRAN compiler to use for testing OpenMP runtime libraries.") + set(OPENMP_LLVM_TOOLS_DIR "" CACHE PATH "Path to LLVM tools for testing.") + + set(CMAKE_CXX_STANDARD 17 CACHE STRING "C++ standard to conform to") + set(CMAKE_CXX_STANDARD_REQUIRED NO) + set(CMAKE_CXX_EXTENSIONS NO) +else() + set(OPENMP_ENABLE_WERROR ${LLVM_ENABLE_WERROR}) + # If building in tree, we honor the same install suffix LLVM uses. + set(OPENMP_INSTALL_LIBDIR "lib${LLVM_LIBDIR_SUFFIX}") + + if (NOT MSVC) + set(OPENMP_TEST_C_COMPILER ${LLVM_RUNTIME_OUTPUT_INTDIR}/clang) + set(OPENMP_TEST_CXX_COMPILER ${LLVM_RUNTIME_OUTPUT_INTDIR}/clang++) + else() + set(OPENMP_TEST_C_COMPILER ${LLVM_RUNTIME_OUTPUT_INTDIR}/clang.exe) + set(OPENMP_TEST_CXX_COMPILER ${LLVM_RUNTIME_OUTPUT_INTDIR}/clang++.exe) + endif() + + # Check for flang + if (NOT MSVC) + set(OPENMP_TEST_Fortran_COMPILER ${LLVM_RUNTIME_OUTPUT_INTDIR}/flang-new) + else() + set(OPENMP_TEST_Fortran_COMPILER ${LLVM_RUNTIME_OUTPUT_INTDIR}/flang-new.exe) + endif() + + # Set fortran test compiler if flang is found + if (EXISTS "${OPENMP_TEST_Fortran_COMPILER}") + message("Using local flang build at ${OPENMP_TEST_Fortran_COMPILER}") + else() + unset(OPENMP_TEST_Fortran_COMPILER) + endif() + + # If not standalone, set CMAKE_CXX_STANDARD but don't set the global cache value, + # only set it locally for OpenMP. + set(CMAKE_CXX_STANDARD 17) + set(CMAKE_CXX_STANDARD_REQUIRED NO) + set(CMAKE_CXX_EXTENSIONS NO) +endif() # Set the path of all resulting libraries to a unified location so that it can # be used for testing. @@ -36,6 +130,9 @@ include(LibomptargetUtils) # Get dependencies for the different components of the project. include(LibomptargetGetDependencies) +# Set up testing infrastructure. +include(OpenMPTesting) + # LLVM source tree is required at build time for libomptarget if (NOT LIBOMPTARGET_LLVM_INCLUDE_DIRS) message(FATAL_ERROR "Missing definition for LIBOMPTARGET_LLVM_INCLUDE_DIRS") @@ -101,6 +198,58 @@ if (LIBOMPTARGET_USE_LTO) list(APPEND offload_link_flags ${CMAKE_CXX_COMPILE_OPTIONS_IPO}) endif() +if(OPENMP_STANDALONE_BUILD) + if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + execute_process( + OUTPUT_STRIP_TRAILING_WHITESPACE + COMMAND ${CMAKE_CXX_COMPILER} --print-resource-dir + RESULT_VARIABLE COMMAND_RETURN_CODE + OUTPUT_VARIABLE COMPILER_RESOURCE_DIR + ) + endif() + + set(LIBOMP_HAVE_OMPT_SUPPORT FALSE) + set(LIBOMP_OMPT_SUPPORT FALSE) + + find_path ( + LIBOMP_OMP_TOOLS_INCLUDE_DIR + NAMES + omp-tools.h + HINTS + ${COMPILER_RESOURCE_DIR}/include + ${CMAKE_INSTALL_PREFIX}/include + ) + + if(LIBOMP_OMP_TOOLS_INCLUDE_DIR) + set(LIBOMP_HAVE_OMPT_SUPPORT TRUE) + set(LIBOMP_OMPT_SUPPORT TRUE) + endif() + + # LLVM_LIBRARY_DIRS set by find_package(LLVM) in LibomptargetGetDependencies + find_library ( + LIBOMP_STANDALONE + NAMES + omp + HINTS + ${CMAKE_INSTALL_PREFIX}/lib + ${LLVM_LIBRARY_DIRS} + REQUIRED + ) +# Check LIBOMP_HAVE_VERSION_SCRIPT_FLAG + include(LLVMCheckCompilerLinkerFlag) + if(NOT APPLE) + llvm_check_compiler_linker_flag(C "-Wl,--version-script=${CMAKE_CURRENT_LIST_DIR}/../openmp/runtime/src/exports_test_so.txt" LIBOMP_HAVE_VERSION_SCRIPT_FLAG) + endif() + + macro(pythonize_bool var) + if (${var}) + set(${var} True) + else() + set(${var} False) + endif() + endmacro() +endif() + # OMPT support for libomptarget # Follow host OMPT support and check if host support has been requested. # LIBOMP_HAVE_OMPT_SUPPORT indicates whether host OMPT support has been implemented. @@ -127,13 +276,10 @@ pythonize_bool(LIBOMPTARGET_GPU_LIBC_SUPPORT) set(LIBOMPTARGET_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include) message(STATUS "OpenMP tools dir in libomptarget: ${LIBOMP_OMP_TOOLS_INCLUDE_DIR}") -include_directories(${LIBOMP_OMP_TOOLS_INCLUDE_DIR}) +if(LIBOMP_OMP_TOOLS_INCLUDE_DIR) + include_directories(${LIBOMP_OMP_TOOLS_INCLUDE_DIR}) +endif() -# Definitions for testing, for reuse when testing libomptarget-nvptx. -set(LIBOMPTARGET_OPENMP_HEADER_FOLDER "${LIBOMP_INCLUDE_DIR}" CACHE STRING - "Path to folder containing omp.h") -set(LIBOMPTARGET_OPENMP_HOST_RTL_FOLDER "${LIBOMP_LIBRARY_DIR}" CACHE STRING - "Path to folder containing libomp.so, and libLLVMSupport.so with profiling enabled") set(LIBOMPTARGET_LLVM_LIBRARY_DIR "${LLVM_LIBRARY_DIR}" CACHE STRING "Path to folder containing llvm library libomptarget.so") set(LIBOMPTARGET_LLVM_LIBRARY_INTDIR "${LIBOMPTARGET_INTDIR}" CACHE STRING diff --git a/openmp/libomptarget/DeviceRTL/CMakeLists.txt b/offload/DeviceRTL/CMakeLists.txt similarity index 99% rename from openmp/libomptarget/DeviceRTL/CMakeLists.txt rename to offload/DeviceRTL/CMakeLists.txt index 2e7f28df24d6..cbc859059100 100644 --- a/openmp/libomptarget/DeviceRTL/CMakeLists.txt +++ b/offload/DeviceRTL/CMakeLists.txt @@ -233,7 +233,7 @@ function(compileDeviceRTLLibrary target_cpu target_name target_triple) set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${bclib_name} ${LIBOMPTARGET_LIBRARY_DIR}/${bclib_name}) # Install bitcode library under the lib destination folder. - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${bclib_name} DESTINATION "${OPENMP_INSTALL_LIBDIR}") + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${bclib_name} DESTINATION "${OFFLOAD_INSTALL_LIBDIR}") set(target_feature "") if("${target_triple}" STREQUAL "nvptx64-nvidia-cuda") @@ -312,4 +312,4 @@ set_target_properties(omptarget.devicertl PROPERTIES ) target_link_libraries(omptarget.devicertl PRIVATE omptarget.devicertl.all_objs) -install(TARGETS omptarget.devicertl ARCHIVE DESTINATION ${OPENMP_INSTALL_LIBDIR}) +install(TARGETS omptarget.devicertl ARCHIVE DESTINATION ${OFFLOAD_INSTALL_LIBDIR}) diff --git a/openmp/libomptarget/DeviceRTL/include/Allocator.h b/offload/DeviceRTL/include/Allocator.h similarity index 100% rename from openmp/libomptarget/DeviceRTL/include/Allocator.h rename to offload/DeviceRTL/include/Allocator.h diff --git a/openmp/libomptarget/DeviceRTL/include/Configuration.h b/offload/DeviceRTL/include/Configuration.h similarity index 100% rename from openmp/libomptarget/DeviceRTL/include/Configuration.h rename to offload/DeviceRTL/include/Configuration.h diff --git a/openmp/libomptarget/DeviceRTL/include/Debug.h b/offload/DeviceRTL/include/Debug.h similarity index 100% rename from openmp/libomptarget/DeviceRTL/include/Debug.h rename to offload/DeviceRTL/include/Debug.h diff --git a/openmp/libomptarget/DeviceRTL/include/Interface.h b/offload/DeviceRTL/include/Interface.h similarity index 100% rename from openmp/libomptarget/DeviceRTL/include/Interface.h rename to offload/DeviceRTL/include/Interface.h diff --git a/openmp/libomptarget/DeviceRTL/include/LibC.h b/offload/DeviceRTL/include/LibC.h similarity index 100% rename from openmp/libomptarget/DeviceRTL/include/LibC.h rename to offload/DeviceRTL/include/LibC.h diff --git a/openmp/libomptarget/DeviceRTL/include/Mapping.h b/offload/DeviceRTL/include/Mapping.h similarity index 100% rename from openmp/libomptarget/DeviceRTL/include/Mapping.h rename to offload/DeviceRTL/include/Mapping.h diff --git a/openmp/libomptarget/DeviceRTL/include/State.h b/offload/DeviceRTL/include/State.h similarity index 100% rename from openmp/libomptarget/DeviceRTL/include/State.h rename to offload/DeviceRTL/include/State.h diff --git a/openmp/libomptarget/DeviceRTL/include/Synchronization.h b/offload/DeviceRTL/include/Synchronization.h similarity index 100% rename from openmp/libomptarget/DeviceRTL/include/Synchronization.h rename to offload/DeviceRTL/include/Synchronization.h diff --git a/openmp/libomptarget/DeviceRTL/include/Types.h b/offload/DeviceRTL/include/Types.h similarity index 100% rename from openmp/libomptarget/DeviceRTL/include/Types.h rename to offload/DeviceRTL/include/Types.h diff --git a/openmp/libomptarget/DeviceRTL/include/Utils.h b/offload/DeviceRTL/include/Utils.h similarity index 100% rename from openmp/libomptarget/DeviceRTL/include/Utils.h rename to offload/DeviceRTL/include/Utils.h diff --git a/openmp/libomptarget/DeviceRTL/include/generated_microtask_cases.gen b/offload/DeviceRTL/include/generated_microtask_cases.gen similarity index 100% rename from openmp/libomptarget/DeviceRTL/include/generated_microtask_cases.gen rename to offload/DeviceRTL/include/generated_microtask_cases.gen diff --git a/openmp/libomptarget/DeviceRTL/src/Allocator.cpp b/offload/DeviceRTL/src/Allocator.cpp similarity index 100% rename from openmp/libomptarget/DeviceRTL/src/Allocator.cpp rename to offload/DeviceRTL/src/Allocator.cpp diff --git a/openmp/libomptarget/DeviceRTL/src/Configuration.cpp b/offload/DeviceRTL/src/Configuration.cpp similarity index 100% rename from openmp/libomptarget/DeviceRTL/src/Configuration.cpp rename to offload/DeviceRTL/src/Configuration.cpp diff --git a/openmp/libomptarget/DeviceRTL/src/Debug.cpp b/offload/DeviceRTL/src/Debug.cpp similarity index 100% rename from openmp/libomptarget/DeviceRTL/src/Debug.cpp rename to offload/DeviceRTL/src/Debug.cpp diff --git a/openmp/libomptarget/DeviceRTL/src/Kernel.cpp b/offload/DeviceRTL/src/Kernel.cpp similarity index 100% rename from openmp/libomptarget/DeviceRTL/src/Kernel.cpp rename to offload/DeviceRTL/src/Kernel.cpp diff --git a/openmp/libomptarget/DeviceRTL/src/LibC.cpp b/offload/DeviceRTL/src/LibC.cpp similarity index 100% rename from openmp/libomptarget/DeviceRTL/src/LibC.cpp rename to offload/DeviceRTL/src/LibC.cpp diff --git a/openmp/libomptarget/DeviceRTL/src/Mapping.cpp b/offload/DeviceRTL/src/Mapping.cpp similarity index 100% rename from openmp/libomptarget/DeviceRTL/src/Mapping.cpp rename to offload/DeviceRTL/src/Mapping.cpp diff --git a/openmp/libomptarget/DeviceRTL/src/Misc.cpp b/offload/DeviceRTL/src/Misc.cpp similarity index 100% rename from openmp/libomptarget/DeviceRTL/src/Misc.cpp rename to offload/DeviceRTL/src/Misc.cpp diff --git a/openmp/libomptarget/DeviceRTL/src/Parallelism.cpp b/offload/DeviceRTL/src/Parallelism.cpp similarity index 100% rename from openmp/libomptarget/DeviceRTL/src/Parallelism.cpp rename to offload/DeviceRTL/src/Parallelism.cpp diff --git a/openmp/libomptarget/DeviceRTL/src/Reduction.cpp b/offload/DeviceRTL/src/Reduction.cpp similarity index 100% rename from openmp/libomptarget/DeviceRTL/src/Reduction.cpp rename to offload/DeviceRTL/src/Reduction.cpp diff --git a/openmp/libomptarget/DeviceRTL/src/State.cpp b/offload/DeviceRTL/src/State.cpp similarity index 100% rename from openmp/libomptarget/DeviceRTL/src/State.cpp rename to offload/DeviceRTL/src/State.cpp diff --git a/openmp/libomptarget/DeviceRTL/src/Stub.cpp b/offload/DeviceRTL/src/Stub.cpp similarity index 100% rename from openmp/libomptarget/DeviceRTL/src/Stub.cpp rename to offload/DeviceRTL/src/Stub.cpp diff --git a/openmp/libomptarget/DeviceRTL/src/Synchronization.cpp b/offload/DeviceRTL/src/Synchronization.cpp similarity index 100% rename from openmp/libomptarget/DeviceRTL/src/Synchronization.cpp rename to offload/DeviceRTL/src/Synchronization.cpp diff --git a/openmp/libomptarget/DeviceRTL/src/Tasking.cpp b/offload/DeviceRTL/src/Tasking.cpp similarity index 100% rename from openmp/libomptarget/DeviceRTL/src/Tasking.cpp rename to offload/DeviceRTL/src/Tasking.cpp diff --git a/openmp/libomptarget/DeviceRTL/src/Utils.cpp b/offload/DeviceRTL/src/Utils.cpp similarity index 100% rename from openmp/libomptarget/DeviceRTL/src/Utils.cpp rename to offload/DeviceRTL/src/Utils.cpp diff --git a/openmp/libomptarget/DeviceRTL/src/Workshare.cpp b/offload/DeviceRTL/src/Workshare.cpp similarity index 100% rename from openmp/libomptarget/DeviceRTL/src/Workshare.cpp rename to offload/DeviceRTL/src/Workshare.cpp diff --git a/openmp/libomptarget/DeviceRTL/src/exports b/offload/DeviceRTL/src/exports similarity index 100% rename from openmp/libomptarget/DeviceRTL/src/exports rename to offload/DeviceRTL/src/exports diff --git a/openmp/libomptarget/README.txt b/offload/README.txt similarity index 100% rename from openmp/libomptarget/README.txt rename to offload/README.txt diff --git a/openmp/libomptarget/cmake/Modules/LibomptargetGetDependencies.cmake b/offload/cmake/Modules/LibomptargetGetDependencies.cmake similarity index 100% rename from openmp/libomptarget/cmake/Modules/LibomptargetGetDependencies.cmake rename to offload/cmake/Modules/LibomptargetGetDependencies.cmake diff --git a/openmp/libomptarget/cmake/Modules/LibomptargetUtils.cmake b/offload/cmake/Modules/LibomptargetUtils.cmake similarity index 100% rename from openmp/libomptarget/cmake/Modules/LibomptargetUtils.cmake rename to offload/cmake/Modules/LibomptargetUtils.cmake diff --git a/offload/cmake/OpenMPTesting.cmake b/offload/cmake/OpenMPTesting.cmake new file mode 100644 index 000000000000..11eafeb76426 --- /dev/null +++ b/offload/cmake/OpenMPTesting.cmake @@ -0,0 +1,238 @@ +# Keep track if we have all dependencies. +set(ENABLE_CHECK_TARGETS TRUE) + +# Function to find required dependencies for testing. +function(find_standalone_test_dependencies) + find_package (Python3 COMPONENTS Interpreter) + + if (NOT Python3_Interpreter_FOUND) + message(STATUS "Could not find Python.") + message(WARNING "The check targets will not be available!") + set(ENABLE_CHECK_TARGETS FALSE PARENT_SCOPE) + return() + else() + set(Python3_EXECUTABLE ${Python3_EXECUTABLE} PARENT_SCOPE) + endif() + + # Find executables. + find_program(OPENMP_LLVM_LIT_EXECUTABLE + NAMES llvm-lit.py llvm-lit lit.py lit + PATHS ${OPENMP_LLVM_TOOLS_DIR}) + if (NOT OPENMP_LLVM_LIT_EXECUTABLE) + message(STATUS "Cannot find llvm-lit.") + message(STATUS "Please put llvm-lit in your PATH, set OPENMP_LLVM_LIT_EXECUTABLE to its full path, or point OPENMP_LLVM_TOOLS_DIR to its directory.") + message(WARNING "The check targets will not be available!") + set(ENABLE_CHECK_TARGETS FALSE PARENT_SCOPE) + return() + endif() + + find_program(OPENMP_FILECHECK_EXECUTABLE + NAMES FileCheck + PATHS ${OPENMP_LLVM_TOOLS_DIR}) + if (NOT OPENMP_FILECHECK_EXECUTABLE) + message(STATUS "Cannot find FileCheck.") + message(STATUS "Please put FileCheck in your PATH, set OPENMP_FILECHECK_EXECUTABLE to its full path, or point OPENMP_LLVM_TOOLS_DIR to its directory.") + message(WARNING "The check targets will not be available!") + set(ENABLE_CHECK_TARGETS FALSE PARENT_SCOPE) + return() + endif() + + find_program(OPENMP_NOT_EXECUTABLE + NAMES not + PATHS ${OPENMP_LLVM_TOOLS_DIR}) + if (NOT OPENMP_NOT_EXECUTABLE) + message(STATUS "Cannot find 'not'.") + message(STATUS "Please put 'not' in your PATH, set OPENMP_NOT_EXECUTABLE to its full path, or point OPENMP_LLVM_TOOLS_DIR to its directory.") + message(WARNING "The check targets will not be available!") + set(ENABLE_CHECK_TARGETS FALSE PARENT_SCOPE) + return() + endif() +endfunction() + +if (${OPENMP_STANDALONE_BUILD}) + find_standalone_test_dependencies() + + # Set lit arguments. + set(DEFAULT_LIT_ARGS "-sv --show-unsupported --show-xfail") + if (MSVC OR XCODE) + set(DEFAULT_LIT_ARGS "${DEFAULT_LIT_ARGS} --no-progress-bar") + endif() + if (${CMAKE_SYSTEM_NAME} MATCHES "AIX") + set(DEFAULT_LIT_ARGS "${DEFAULT_LIT_ARGS} --time-tests --timeout=1800") + endif() + set(OPENMP_LIT_ARGS "${DEFAULT_LIT_ARGS}" CACHE STRING "Options for lit.") + separate_arguments(OPENMP_LIT_ARGS) +else() + if (NOT TARGET "FileCheck") + message(STATUS "Cannot find 'FileCheck'.") + message(WARNING "The check targets will not be available!") + set(ENABLE_CHECK_TARGETS FALSE) + else() + set(OPENMP_FILECHECK_EXECUTABLE ${LLVM_RUNTIME_OUTPUT_INTDIR}/FileCheck) + endif() + set(OPENMP_NOT_EXECUTABLE ${LLVM_RUNTIME_OUTPUT_INTDIR}/not) +endif() + +# Macro to extract information about compiler from file. (no own scope) +macro(extract_test_compiler_information lang file) + file(READ ${file} information) + list(GET information 0 path) + list(GET information 1 id) + list(GET information 2 version) + list(GET information 3 openmp_flags) + list(GET information 4 has_tsan_flags) + list(GET information 5 has_omit_frame_pointer_flags) + list(GET information 6 has_omp_h) + + set(OPENMP_TEST_${lang}_COMPILER_PATH ${path}) + set(OPENMP_TEST_${lang}_COMPILER_ID ${id}) + set(OPENMP_TEST_${lang}_COMPILER_VERSION ${version}) + set(OPENMP_TEST_${lang}_COMPILER_OPENMP_FLAGS ${openmp_flags}) + set(OPENMP_TEST_${lang}_COMPILER_HAS_TSAN_FLAGS ${has_tsan_flags}) + set(OPENMP_TEST_${lang}_COMPILER_HAS_OMIT_FRAME_POINTER_FLAGS ${has_omit_frame_pointer_flags}) + set(OPENMP_TEST_${lang}_COMPILER_HAS_OMP_H ${has_omp_h}) +endmacro() + +# Function to set variables with information about the test compiler. +function(set_test_compiler_information dir) + extract_test_compiler_information(C ${dir}/CCompilerInformation.txt) + extract_test_compiler_information(CXX ${dir}/CXXCompilerInformation.txt) + if (NOT("${OPENMP_TEST_C_COMPILER_ID}" STREQUAL "${OPENMP_TEST_CXX_COMPILER_ID}" AND + "${OPENMP_TEST_C_COMPILER_VERSION}" STREQUAL "${OPENMP_TEST_CXX_COMPILER_VERSION}")) + message(STATUS "Test compilers for C and C++ don't match.") + message(WARNING "The check targets will not be available!") + set(ENABLE_CHECK_TARGETS FALSE PARENT_SCOPE) + else() + set(OPENMP_TEST_COMPILER_ID "${OPENMP_TEST_C_COMPILER_ID}" PARENT_SCOPE) + set(OPENMP_TEST_COMPILER_VERSION "${OPENMP_TEST_C_COMPILER_VERSION}" PARENT_SCOPE) + set(OPENMP_TEST_COMPILER_OPENMP_FLAGS "${OPENMP_TEST_C_COMPILER_OPENMP_FLAGS}" PARENT_SCOPE) + set(OPENMP_TEST_COMPILER_HAS_TSAN_FLAGS "${OPENMP_TEST_C_COMPILER_HAS_TSAN_FLAGS}" PARENT_SCOPE) + set(OPENMP_TEST_COMPILER_HAS_OMIT_FRAME_POINTER_FLAGS "${OPENMP_TEST_C_COMPILER_HAS_OMIT_FRAME_POINTER_FLAGS}" PARENT_SCOPE) + set(OPENMP_TEST_COMPILER_HAS_OMP_H "${OPENMP_TEST_C_COMPILER_HAS_OMP_H}" PARENT_SCOPE) + + # Determine major version. + string(REGEX MATCH "[0-9]+" major "${OPENMP_TEST_C_COMPILER_VERSION}") + string(REGEX MATCH "[0-9]+\\.[0-9]+" majorminor "${OPENMP_TEST_C_COMPILER_VERSION}") + set(OPENMP_TEST_COMPILER_VERSION_MAJOR "${major}" PARENT_SCOPE) + set(OPENMP_TEST_COMPILER_VERSION_MAJOR_MINOR "${majorminor}" PARENT_SCOPE) + endif() +endfunction() + +if (${OPENMP_STANDALONE_BUILD}) + # Detect compiler that should be used for testing. + # We cannot use ExternalProject_Add() because its configuration runs when this + # project is built which is too late for detecting the compiler... + file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/DetectTestCompiler) + execute_process( + COMMAND ${CMAKE_COMMAND} -G${CMAKE_GENERATOR} ${CMAKE_CURRENT_LIST_DIR}/DetectTestCompiler + -DCMAKE_C_COMPILER=${OPENMP_TEST_C_COMPILER} + -DCMAKE_CXX_COMPILER=${OPENMP_TEST_CXX_COMPILER} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/DetectTestCompiler + OUTPUT_VARIABLE DETECT_COMPILER_OUT + ERROR_VARIABLE DETECT_COMPILER_ERR + RESULT_VARIABLE DETECT_COMPILER_RESULT) + if (DETECT_COMPILER_RESULT) + message(STATUS "Could not detect test compilers.") + message(WARNING "The check targets will not be available!") + set(ENABLE_CHECK_TARGETS FALSE) + else() + set_test_compiler_information(${CMAKE_CURRENT_BINARY_DIR}/DetectTestCompiler) + endif() +else() + # Set the information that we know. + set(OPENMP_TEST_COMPILER_ID "Clang") + # Cannot use CLANG_VERSION because we are not guaranteed that this is already set. + set(OPENMP_TEST_COMPILER_VERSION "${LLVM_VERSION}") + set(OPENMP_TEST_COMPILER_VERSION_MAJOR "${LLVM_VERSION_MAJOR}") + set(OPENMP_TEST_COMPILER_VERSION_MAJOR_MINOR "${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}") + # Unfortunately the top-level cmake/config-ix.cmake file mangles CMake's + # CMAKE_THREAD_LIBS_INIT variable from the FindThreads package, so work + # around that, until it is fixed there. + if("${CMAKE_THREAD_LIBS_INIT}" STREQUAL "-lpthread") + set(OPENMP_TEST_COMPILER_THREAD_FLAGS "-pthread") + else() + set(OPENMP_TEST_COMPILER_THREAD_FLAGS "${CMAKE_THREAD_LIBS_INIT}") + endif() + if(TARGET tsan) + set(OPENMP_TEST_COMPILER_HAS_TSAN_FLAGS 1) + else() + set(OPENMP_TEST_COMPILER_HAS_TSAN_FLAGS 0) + endif() + set(OPENMP_TEST_COMPILER_HAS_OMP_H 1) + set(OPENMP_TEST_COMPILER_OPENMP_FLAGS "-fopenmp ${OPENMP_TEST_COMPILER_THREAD_FLAGS}") + set(OPENMP_TEST_COMPILER_HAS_OMIT_FRAME_POINTER_FLAGS 1) +endif() + +# Function to set compiler features for use in lit. +function(update_test_compiler_features) + set(FEATURES "[") + set(first TRUE) + foreach(feat IN LISTS OPENMP_TEST_COMPILER_FEATURE_LIST) + if (NOT first) + string(APPEND FEATURES ", ") + endif() + set(first FALSE) + string(APPEND FEATURES "'${feat}'") + endforeach() + string(APPEND FEATURES "]") + set(OPENMP_TEST_COMPILER_FEATURES ${FEATURES} PARENT_SCOPE) +endfunction() + +function(set_test_compiler_features) + if ("${OPENMP_TEST_COMPILER_ID}" STREQUAL "GNU") + set(comp "gcc") + elseif ("${OPENMP_TEST_COMPILER_ID}" STREQUAL "Intel") + set(comp "icc") + else() + # Just use the lowercase of the compiler ID as fallback. + string(TOLOWER "${OPENMP_TEST_COMPILER_ID}" comp) + endif() + set(OPENMP_TEST_COMPILER_FEATURE_LIST ${comp} ${comp}-${OPENMP_TEST_COMPILER_VERSION_MAJOR} ${comp}-${OPENMP_TEST_COMPILER_VERSION_MAJOR_MINOR} ${comp}-${OPENMP_TEST_COMPILER_VERSION} PARENT_SCOPE) +endfunction() +set_test_compiler_features() +update_test_compiler_features() + +# Function to add a testsuite for an OpenMP runtime library. +function(add_offload_testsuite target comment) + if (NOT ENABLE_CHECK_TARGETS) + add_custom_target(${target} + COMMAND ${CMAKE_COMMAND} -E echo "${target} does nothing, dependencies not found.") + message(STATUS "${target} does nothing.") + return() + endif() + + cmake_parse_arguments(ARG "EXCLUDE_FROM_CHECK_ALL" "" "DEPENDS;ARGS" ${ARGN}) + # EXCLUDE_FROM_CHECK_ALL excludes the test ${target} out of check-offload. + if (NOT ARG_EXCLUDE_FROM_CHECK_ALL) + # Register the testsuites and depends for the check-offload rule. + set_property(GLOBAL APPEND PROPERTY OPENMP_LIT_TESTSUITES ${ARG_UNPARSED_ARGUMENTS}) + set_property(GLOBAL APPEND PROPERTY OPENMP_LIT_DEPENDS ${ARG_DEPENDS}) + endif() + + if (${OPENMP_STANDALONE_BUILD}) + set(LIT_ARGS ${OPENMP_LIT_ARGS} ${ARG_ARGS}) + add_custom_target(${target} + COMMAND ${Python3_EXECUTABLE} ${OPENMP_LLVM_LIT_EXECUTABLE} ${LIT_ARGS} ${ARG_UNPARSED_ARGUMENTS} + COMMENT ${comment} + DEPENDS ${ARG_DEPENDS} + USES_TERMINAL + ) + else() + if (ARG_EXCLUDE_FROM_CHECK_ALL) + add_lit_testsuite(${target} + ${comment} + ${ARG_UNPARSED_ARGUMENTS} + EXCLUDE_FROM_CHECK_ALL + DEPENDS clang FileCheck not ${ARG_DEPENDS} + ARGS ${ARG_ARGS} + ) + else() + add_lit_testsuite(${target} + ${comment} + ${ARG_UNPARSED_ARGUMENTS} + DEPENDS clang FileCheck not ${ARG_DEPENDS} + ARGS ${ARG_ARGS} + ) + endif() + endif() +endfunction() diff --git a/openmp/libomptarget/docs/declare_target_indirect.md b/offload/docs/declare_target_indirect.md similarity index 100% rename from openmp/libomptarget/docs/declare_target_indirect.md rename to offload/docs/declare_target_indirect.md diff --git a/openmp/libomptarget/include/DeviceImage.h b/offload/include/DeviceImage.h similarity index 100% rename from openmp/libomptarget/include/DeviceImage.h rename to offload/include/DeviceImage.h diff --git a/openmp/libomptarget/include/ExclusiveAccess.h b/offload/include/ExclusiveAccess.h similarity index 100% rename from openmp/libomptarget/include/ExclusiveAccess.h rename to offload/include/ExclusiveAccess.h diff --git a/openmp/libomptarget/include/OffloadEntry.h b/offload/include/OffloadEntry.h similarity index 100% rename from openmp/libomptarget/include/OffloadEntry.h rename to offload/include/OffloadEntry.h diff --git a/openmp/libomptarget/include/OffloadPolicy.h b/offload/include/OffloadPolicy.h similarity index 100% rename from openmp/libomptarget/include/OffloadPolicy.h rename to offload/include/OffloadPolicy.h diff --git a/openmp/libomptarget/include/OpenMP/InternalTypes.h b/offload/include/OpenMP/InternalTypes.h similarity index 100% rename from openmp/libomptarget/include/OpenMP/InternalTypes.h rename to offload/include/OpenMP/InternalTypes.h diff --git a/openmp/libomptarget/include/OpenMP/InteropAPI.h b/offload/include/OpenMP/InteropAPI.h similarity index 100% rename from openmp/libomptarget/include/OpenMP/InteropAPI.h rename to offload/include/OpenMP/InteropAPI.h diff --git a/openmp/libomptarget/include/OpenMP/Mapping.h b/offload/include/OpenMP/Mapping.h similarity index 100% rename from openmp/libomptarget/include/OpenMP/Mapping.h rename to offload/include/OpenMP/Mapping.h diff --git a/openmp/libomptarget/include/OpenMP/OMPT/Callback.h b/offload/include/OpenMP/OMPT/Callback.h similarity index 100% rename from openmp/libomptarget/include/OpenMP/OMPT/Callback.h rename to offload/include/OpenMP/OMPT/Callback.h diff --git a/openmp/libomptarget/include/OpenMP/OMPT/Connector.h b/offload/include/OpenMP/OMPT/Connector.h similarity index 100% rename from openmp/libomptarget/include/OpenMP/OMPT/Connector.h rename to offload/include/OpenMP/OMPT/Connector.h diff --git a/openmp/libomptarget/include/OpenMP/OMPT/Interface.h b/offload/include/OpenMP/OMPT/Interface.h similarity index 100% rename from openmp/libomptarget/include/OpenMP/OMPT/Interface.h rename to offload/include/OpenMP/OMPT/Interface.h diff --git a/openmp/libomptarget/include/OpenMP/omp.h b/offload/include/OpenMP/omp.h similarity index 100% rename from openmp/libomptarget/include/OpenMP/omp.h rename to offload/include/OpenMP/omp.h diff --git a/openmp/libomptarget/include/PluginManager.h b/offload/include/PluginManager.h similarity index 100% rename from openmp/libomptarget/include/PluginManager.h rename to offload/include/PluginManager.h diff --git a/openmp/libomptarget/include/Shared/APITypes.h b/offload/include/Shared/APITypes.h similarity index 100% rename from openmp/libomptarget/include/Shared/APITypes.h rename to offload/include/Shared/APITypes.h diff --git a/openmp/libomptarget/include/Shared/Debug.h b/offload/include/Shared/Debug.h similarity index 100% rename from openmp/libomptarget/include/Shared/Debug.h rename to offload/include/Shared/Debug.h diff --git a/openmp/libomptarget/include/Shared/Environment.h b/offload/include/Shared/Environment.h similarity index 100% rename from openmp/libomptarget/include/Shared/Environment.h rename to offload/include/Shared/Environment.h diff --git a/openmp/libomptarget/include/Shared/EnvironmentVar.h b/offload/include/Shared/EnvironmentVar.h similarity index 100% rename from openmp/libomptarget/include/Shared/EnvironmentVar.h rename to offload/include/Shared/EnvironmentVar.h diff --git a/openmp/libomptarget/include/Shared/PluginAPI.h b/offload/include/Shared/PluginAPI.h similarity index 100% rename from openmp/libomptarget/include/Shared/PluginAPI.h rename to offload/include/Shared/PluginAPI.h diff --git a/openmp/libomptarget/include/Shared/PluginAPI.inc b/offload/include/Shared/PluginAPI.inc similarity index 100% rename from openmp/libomptarget/include/Shared/PluginAPI.inc rename to offload/include/Shared/PluginAPI.inc diff --git a/openmp/libomptarget/include/Shared/Profile.h b/offload/include/Shared/Profile.h similarity index 100% rename from openmp/libomptarget/include/Shared/Profile.h rename to offload/include/Shared/Profile.h diff --git a/openmp/libomptarget/include/Shared/Requirements.h b/offload/include/Shared/Requirements.h similarity index 100% rename from openmp/libomptarget/include/Shared/Requirements.h rename to offload/include/Shared/Requirements.h diff --git a/openmp/libomptarget/include/Shared/SourceInfo.h b/offload/include/Shared/SourceInfo.h similarity index 100% rename from openmp/libomptarget/include/Shared/SourceInfo.h rename to offload/include/Shared/SourceInfo.h diff --git a/openmp/libomptarget/include/Shared/Utils.h b/offload/include/Shared/Utils.h similarity index 100% rename from openmp/libomptarget/include/Shared/Utils.h rename to offload/include/Shared/Utils.h diff --git a/openmp/libomptarget/include/Utils/ExponentialBackoff.h b/offload/include/Utils/ExponentialBackoff.h similarity index 100% rename from openmp/libomptarget/include/Utils/ExponentialBackoff.h rename to offload/include/Utils/ExponentialBackoff.h diff --git a/openmp/libomptarget/include/device.h b/offload/include/device.h similarity index 100% rename from openmp/libomptarget/include/device.h rename to offload/include/device.h diff --git a/openmp/libomptarget/include/omptarget.h b/offload/include/omptarget.h similarity index 100% rename from openmp/libomptarget/include/omptarget.h rename to offload/include/omptarget.h diff --git a/openmp/libomptarget/include/rtl.h b/offload/include/rtl.h similarity index 100% rename from openmp/libomptarget/include/rtl.h rename to offload/include/rtl.h diff --git a/openmp/libomptarget/plugins-nextgen/CMakeLists.txt b/offload/plugins-nextgen/CMakeLists.txt similarity index 100% rename from openmp/libomptarget/plugins-nextgen/CMakeLists.txt rename to offload/plugins-nextgen/CMakeLists.txt diff --git a/openmp/libomptarget/plugins-nextgen/amdgpu/CMakeLists.txt b/offload/plugins-nextgen/amdgpu/CMakeLists.txt similarity index 97% rename from openmp/libomptarget/plugins-nextgen/amdgpu/CMakeLists.txt rename to offload/plugins-nextgen/amdgpu/CMakeLists.txt index 40df77102c78..f5f7096137c2 100644 --- a/openmp/libomptarget/plugins-nextgen/amdgpu/CMakeLists.txt +++ b/offload/plugins-nextgen/amdgpu/CMakeLists.txt @@ -59,6 +59,6 @@ else() endif() # Install plugin under the lib destination folder. -install(TARGETS omptarget.rtl.amdgpu LIBRARY DESTINATION "${OPENMP_INSTALL_LIBDIR}") +install(TARGETS omptarget.rtl.amdgpu LIBRARY DESTINATION "${OFFLOAD_INSTALL_LIBDIR}") set_target_properties(omptarget.rtl.amdgpu PROPERTIES INSTALL_RPATH "$ORIGIN" BUILD_RPATH "$ORIGIN:${CMAKE_CURRENT_BINARY_DIR}/..") diff --git a/openmp/libomptarget/plugins-nextgen/amdgpu/dynamic_hsa/hsa.cpp b/offload/plugins-nextgen/amdgpu/dynamic_hsa/hsa.cpp similarity index 100% rename from openmp/libomptarget/plugins-nextgen/amdgpu/dynamic_hsa/hsa.cpp rename to offload/plugins-nextgen/amdgpu/dynamic_hsa/hsa.cpp diff --git a/openmp/libomptarget/plugins-nextgen/amdgpu/dynamic_hsa/hsa.h b/offload/plugins-nextgen/amdgpu/dynamic_hsa/hsa.h similarity index 100% rename from openmp/libomptarget/plugins-nextgen/amdgpu/dynamic_hsa/hsa.h rename to offload/plugins-nextgen/amdgpu/dynamic_hsa/hsa.h diff --git a/openmp/libomptarget/plugins-nextgen/amdgpu/dynamic_hsa/hsa_ext_amd.h b/offload/plugins-nextgen/amdgpu/dynamic_hsa/hsa_ext_amd.h similarity index 100% rename from openmp/libomptarget/plugins-nextgen/amdgpu/dynamic_hsa/hsa_ext_amd.h rename to offload/plugins-nextgen/amdgpu/dynamic_hsa/hsa_ext_amd.h diff --git a/openmp/libomptarget/plugins-nextgen/amdgpu/src/rtl.cpp b/offload/plugins-nextgen/amdgpu/src/rtl.cpp similarity index 100% rename from openmp/libomptarget/plugins-nextgen/amdgpu/src/rtl.cpp rename to offload/plugins-nextgen/amdgpu/src/rtl.cpp diff --git a/openmp/libomptarget/plugins-nextgen/amdgpu/utils/UtilitiesRTL.h b/offload/plugins-nextgen/amdgpu/utils/UtilitiesRTL.h similarity index 100% rename from openmp/libomptarget/plugins-nextgen/amdgpu/utils/UtilitiesRTL.h rename to offload/plugins-nextgen/amdgpu/utils/UtilitiesRTL.h diff --git a/openmp/libomptarget/plugins-nextgen/common/CMakeLists.txt b/offload/plugins-nextgen/common/CMakeLists.txt similarity index 100% rename from openmp/libomptarget/plugins-nextgen/common/CMakeLists.txt rename to offload/plugins-nextgen/common/CMakeLists.txt diff --git a/openmp/libomptarget/plugins-nextgen/common/OMPT/OmptCallback.cpp b/offload/plugins-nextgen/common/OMPT/OmptCallback.cpp similarity index 100% rename from openmp/libomptarget/plugins-nextgen/common/OMPT/OmptCallback.cpp rename to offload/plugins-nextgen/common/OMPT/OmptCallback.cpp diff --git a/openmp/libomptarget/plugins-nextgen/common/include/DLWrap.h b/offload/plugins-nextgen/common/include/DLWrap.h similarity index 100% rename from openmp/libomptarget/plugins-nextgen/common/include/DLWrap.h rename to offload/plugins-nextgen/common/include/DLWrap.h diff --git a/openmp/libomptarget/plugins-nextgen/common/include/GlobalHandler.h b/offload/plugins-nextgen/common/include/GlobalHandler.h similarity index 100% rename from openmp/libomptarget/plugins-nextgen/common/include/GlobalHandler.h rename to offload/plugins-nextgen/common/include/GlobalHandler.h diff --git a/openmp/libomptarget/plugins-nextgen/common/include/JIT.h b/offload/plugins-nextgen/common/include/JIT.h similarity index 100% rename from openmp/libomptarget/plugins-nextgen/common/include/JIT.h rename to offload/plugins-nextgen/common/include/JIT.h diff --git a/openmp/libomptarget/plugins-nextgen/common/include/MemoryManager.h b/offload/plugins-nextgen/common/include/MemoryManager.h similarity index 100% rename from openmp/libomptarget/plugins-nextgen/common/include/MemoryManager.h rename to offload/plugins-nextgen/common/include/MemoryManager.h diff --git a/openmp/libomptarget/plugins-nextgen/common/include/PluginInterface.h b/offload/plugins-nextgen/common/include/PluginInterface.h similarity index 100% rename from openmp/libomptarget/plugins-nextgen/common/include/PluginInterface.h rename to offload/plugins-nextgen/common/include/PluginInterface.h diff --git a/openmp/libomptarget/plugins-nextgen/common/include/RPC.h b/offload/plugins-nextgen/common/include/RPC.h similarity index 100% rename from openmp/libomptarget/plugins-nextgen/common/include/RPC.h rename to offload/plugins-nextgen/common/include/RPC.h diff --git a/openmp/libomptarget/plugins-nextgen/common/include/Utils/ELF.h b/offload/plugins-nextgen/common/include/Utils/ELF.h similarity index 100% rename from openmp/libomptarget/plugins-nextgen/common/include/Utils/ELF.h rename to offload/plugins-nextgen/common/include/Utils/ELF.h diff --git a/openmp/libomptarget/plugins-nextgen/common/src/GlobalHandler.cpp b/offload/plugins-nextgen/common/src/GlobalHandler.cpp similarity index 100% rename from openmp/libomptarget/plugins-nextgen/common/src/GlobalHandler.cpp rename to offload/plugins-nextgen/common/src/GlobalHandler.cpp diff --git a/openmp/libomptarget/plugins-nextgen/common/src/JIT.cpp b/offload/plugins-nextgen/common/src/JIT.cpp similarity index 100% rename from openmp/libomptarget/plugins-nextgen/common/src/JIT.cpp rename to offload/plugins-nextgen/common/src/JIT.cpp diff --git a/openmp/libomptarget/plugins-nextgen/common/src/PluginInterface.cpp b/offload/plugins-nextgen/common/src/PluginInterface.cpp similarity index 100% rename from openmp/libomptarget/plugins-nextgen/common/src/PluginInterface.cpp rename to offload/plugins-nextgen/common/src/PluginInterface.cpp diff --git a/openmp/libomptarget/plugins-nextgen/common/src/RPC.cpp b/offload/plugins-nextgen/common/src/RPC.cpp similarity index 100% rename from openmp/libomptarget/plugins-nextgen/common/src/RPC.cpp rename to offload/plugins-nextgen/common/src/RPC.cpp diff --git a/openmp/libomptarget/plugins-nextgen/common/src/Utils/ELF.cpp b/offload/plugins-nextgen/common/src/Utils/ELF.cpp similarity index 100% rename from openmp/libomptarget/plugins-nextgen/common/src/Utils/ELF.cpp rename to offload/plugins-nextgen/common/src/Utils/ELF.cpp diff --git a/openmp/libomptarget/plugins-nextgen/cuda/CMakeLists.txt b/offload/plugins-nextgen/cuda/CMakeLists.txt similarity index 96% rename from openmp/libomptarget/plugins-nextgen/cuda/CMakeLists.txt rename to offload/plugins-nextgen/cuda/CMakeLists.txt index b3530462aa19..0284bd22d2a4 100644 --- a/openmp/libomptarget/plugins-nextgen/cuda/CMakeLists.txt +++ b/offload/plugins-nextgen/cuda/CMakeLists.txt @@ -53,6 +53,6 @@ else() endif() # Install plugin under the lib destination folder. -install(TARGETS omptarget.rtl.cuda LIBRARY DESTINATION "${OPENMP_INSTALL_LIBDIR}") +install(TARGETS omptarget.rtl.cuda LIBRARY DESTINATION "${OFFLOAD_INSTALL_LIBDIR}") set_target_properties(omptarget.rtl.cuda PROPERTIES INSTALL_RPATH "$ORIGIN" BUILD_RPATH "$ORIGIN:${CMAKE_CURRENT_BINARY_DIR}/..") diff --git a/openmp/libomptarget/plugins-nextgen/cuda/dynamic_cuda/cuda.cpp b/offload/plugins-nextgen/cuda/dynamic_cuda/cuda.cpp similarity index 100% rename from openmp/libomptarget/plugins-nextgen/cuda/dynamic_cuda/cuda.cpp rename to offload/plugins-nextgen/cuda/dynamic_cuda/cuda.cpp diff --git a/openmp/libomptarget/plugins-nextgen/cuda/dynamic_cuda/cuda.h b/offload/plugins-nextgen/cuda/dynamic_cuda/cuda.h similarity index 100% rename from openmp/libomptarget/plugins-nextgen/cuda/dynamic_cuda/cuda.h rename to offload/plugins-nextgen/cuda/dynamic_cuda/cuda.h diff --git a/openmp/libomptarget/plugins-nextgen/cuda/src/rtl.cpp b/offload/plugins-nextgen/cuda/src/rtl.cpp similarity index 100% rename from openmp/libomptarget/plugins-nextgen/cuda/src/rtl.cpp rename to offload/plugins-nextgen/cuda/src/rtl.cpp diff --git a/openmp/libomptarget/plugins-nextgen/exports b/offload/plugins-nextgen/exports similarity index 100% rename from openmp/libomptarget/plugins-nextgen/exports rename to offload/plugins-nextgen/exports diff --git a/openmp/libomptarget/plugins-nextgen/host/CMakeLists.txt b/offload/plugins-nextgen/host/CMakeLists.txt similarity index 98% rename from openmp/libomptarget/plugins-nextgen/host/CMakeLists.txt rename to offload/plugins-nextgen/host/CMakeLists.txt index c1493d293d30..7da18ee278d4 100644 --- a/openmp/libomptarget/plugins-nextgen/host/CMakeLists.txt +++ b/offload/plugins-nextgen/host/CMakeLists.txt @@ -33,7 +33,7 @@ endif() # Install plugin under the lib destination folder. install(TARGETS omptarget.rtl.${machine} - LIBRARY DESTINATION "${OPENMP_INSTALL_LIBDIR}") + LIBRARY DESTINATION "${OFFLOAD_INSTALL_LIBDIR}") set_target_properties(omptarget.rtl.${machine} PROPERTIES INSTALL_RPATH "$ORIGIN" BUILD_RPATH "$ORIGIN:${CMAKE_CURRENT_BINARY_DIR}/.." POSITION_INDEPENDENT_CODE ON diff --git a/openmp/libomptarget/plugins-nextgen/host/dynamic_ffi/ffi.cpp b/offload/plugins-nextgen/host/dynamic_ffi/ffi.cpp similarity index 100% rename from openmp/libomptarget/plugins-nextgen/host/dynamic_ffi/ffi.cpp rename to offload/plugins-nextgen/host/dynamic_ffi/ffi.cpp diff --git a/openmp/libomptarget/plugins-nextgen/host/dynamic_ffi/ffi.h b/offload/plugins-nextgen/host/dynamic_ffi/ffi.h similarity index 100% rename from openmp/libomptarget/plugins-nextgen/host/dynamic_ffi/ffi.h rename to offload/plugins-nextgen/host/dynamic_ffi/ffi.h diff --git a/openmp/libomptarget/plugins-nextgen/host/src/rtl.cpp b/offload/plugins-nextgen/host/src/rtl.cpp similarity index 100% rename from openmp/libomptarget/plugins-nextgen/host/src/rtl.cpp rename to offload/plugins-nextgen/host/src/rtl.cpp diff --git a/openmp/libomptarget/src/CMakeLists.txt b/offload/src/CMakeLists.txt similarity index 95% rename from openmp/libomptarget/src/CMakeLists.txt rename to offload/src/CMakeLists.txt index d0971bd4ef07..fb1ad3d7ae70 100644 --- a/openmp/libomptarget/src/CMakeLists.txt +++ b/offload/src/CMakeLists.txt @@ -12,6 +12,12 @@ libomptarget_say("Building offloading runtime library libomptarget.") +if(LIBOMP_STANDALONE) + set(LIBOMP ${LIBOMP_STANDALONE}) +else() + set(LIBOMP omp) +endif() + add_llvm_library(omptarget SHARED @@ -38,7 +44,7 @@ add_llvm_library(omptarget LINK_LIBS PUBLIC - omp + ${LIBOMP} NO_INSTALL_RPATH BUILDTREE_ONLY @@ -87,4 +93,4 @@ set_target_properties(omptarget PROPERTIES POSITION_INDEPENDENT_CODE ON INSTALL_RPATH "$ORIGIN" BUILD_RPATH "$ORIGIN:${CMAKE_CURRENT_BINARY_DIR}/..") -install(TARGETS omptarget LIBRARY COMPONENT omptarget DESTINATION "${OPENMP_INSTALL_LIBDIR}") +install(TARGETS omptarget LIBRARY COMPONENT omptarget DESTINATION "${OFFLOAD_INSTALL_LIBDIR}") diff --git a/openmp/libomptarget/src/DeviceImage.cpp b/offload/src/DeviceImage.cpp similarity index 100% rename from openmp/libomptarget/src/DeviceImage.cpp rename to offload/src/DeviceImage.cpp diff --git a/openmp/libomptarget/src/LegacyAPI.cpp b/offload/src/LegacyAPI.cpp similarity index 100% rename from openmp/libomptarget/src/LegacyAPI.cpp rename to offload/src/LegacyAPI.cpp diff --git a/openmp/libomptarget/src/OffloadRTL.cpp b/offload/src/OffloadRTL.cpp similarity index 100% rename from openmp/libomptarget/src/OffloadRTL.cpp rename to offload/src/OffloadRTL.cpp diff --git a/openmp/libomptarget/src/OpenMP/API.cpp b/offload/src/OpenMP/API.cpp similarity index 100% rename from openmp/libomptarget/src/OpenMP/API.cpp rename to offload/src/OpenMP/API.cpp diff --git a/openmp/libomptarget/src/OpenMP/InteropAPI.cpp b/offload/src/OpenMP/InteropAPI.cpp similarity index 100% rename from openmp/libomptarget/src/OpenMP/InteropAPI.cpp rename to offload/src/OpenMP/InteropAPI.cpp diff --git a/openmp/libomptarget/src/OpenMP/Mapping.cpp b/offload/src/OpenMP/Mapping.cpp similarity index 100% rename from openmp/libomptarget/src/OpenMP/Mapping.cpp rename to offload/src/OpenMP/Mapping.cpp diff --git a/openmp/libomptarget/src/OpenMP/OMPT/Callback.cpp b/offload/src/OpenMP/OMPT/Callback.cpp similarity index 100% rename from openmp/libomptarget/src/OpenMP/OMPT/Callback.cpp rename to offload/src/OpenMP/OMPT/Callback.cpp diff --git a/openmp/libomptarget/src/PluginManager.cpp b/offload/src/PluginManager.cpp similarity index 100% rename from openmp/libomptarget/src/PluginManager.cpp rename to offload/src/PluginManager.cpp diff --git a/openmp/libomptarget/src/device.cpp b/offload/src/device.cpp similarity index 100% rename from openmp/libomptarget/src/device.cpp rename to offload/src/device.cpp diff --git a/openmp/libomptarget/src/exports b/offload/src/exports similarity index 100% rename from openmp/libomptarget/src/exports rename to offload/src/exports diff --git a/openmp/libomptarget/src/interface.cpp b/offload/src/interface.cpp similarity index 100% rename from openmp/libomptarget/src/interface.cpp rename to offload/src/interface.cpp diff --git a/openmp/libomptarget/src/omptarget.cpp b/offload/src/omptarget.cpp similarity index 100% rename from openmp/libomptarget/src/omptarget.cpp rename to offload/src/omptarget.cpp diff --git a/openmp/libomptarget/src/private.h b/offload/src/private.h similarity index 100% rename from openmp/libomptarget/src/private.h rename to offload/src/private.h diff --git a/openmp/libomptarget/test/CMakeLists.txt b/offload/test/CMakeLists.txt similarity index 78% rename from openmp/libomptarget/test/CMakeLists.txt rename to offload/test/CMakeLists.txt index a0ba233eaa57..59c9dd98f712 100644 --- a/openmp/libomptarget/test/CMakeLists.txt +++ b/offload/test/CMakeLists.txt @@ -1,6 +1,6 @@ # CMakeLists.txt file for unit testing OpenMP offloading runtime library. -if(NOT OPENMP_TEST_COMPILER_ID STREQUAL "Clang" OR - OPENMP_TEST_COMPILER_VERSION VERSION_LESS 6.0.0) +if(NOT CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR + CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.0.0) libomptarget_say("Can only test with Clang compiler in version 6.0.0 or later.") libomptarget_warning_say("The check-libomptarget target will not be available!") return() @@ -20,7 +20,7 @@ string(REGEX MATCHALL "([^\ ]+\ |[^\ ]+$)" SYSTEM_TARGETS "${LIBOMPTARGET_SYSTEM foreach(CURRENT_TARGET IN LISTS SYSTEM_TARGETS) string(STRIP "${CURRENT_TARGET}" CURRENT_TARGET) - add_openmp_testsuite(check-libomptarget-${CURRENT_TARGET} + add_offload_testsuite(check-libomptarget-${CURRENT_TARGET} "Running libomptarget tests" ${CMAKE_CURRENT_BINARY_DIR}/${CURRENT_TARGET} DEPENDS omptarget omp ${LIBOMPTARGET_TESTED_PLUGINS} @@ -34,7 +34,14 @@ foreach(CURRENT_TARGET IN LISTS SYSTEM_TARGETS) endforeach() -add_openmp_testsuite(check-libomptarget +add_offload_testsuite(check-libomptarget + "Running libomptarget tests" + ${LIBOMPTARGET_LIT_TESTSUITES} + EXCLUDE_FROM_CHECK_ALL + DEPENDS omptarget omp ${LIBOMPTARGET_TESTED_PLUGINS} + ARGS ${LIBOMPTARGET_LIT_ARG_LIST}) + +add_offload_testsuite(check-offload "Running libomptarget tests" ${LIBOMPTARGET_LIT_TESTSUITES} EXCLUDE_FROM_CHECK_ALL diff --git a/openmp/libomptarget/test/Inputs/basic_array.f90 b/offload/test/Inputs/basic_array.f90 similarity index 100% rename from openmp/libomptarget/test/Inputs/basic_array.f90 rename to offload/test/Inputs/basic_array.f90 diff --git a/openmp/libomptarget/test/Inputs/declare_indirect_func.c b/offload/test/Inputs/declare_indirect_func.c similarity index 100% rename from openmp/libomptarget/test/Inputs/declare_indirect_func.c rename to offload/test/Inputs/declare_indirect_func.c diff --git a/openmp/libomptarget/test/api/assert.c b/offload/test/api/assert.c similarity index 100% rename from openmp/libomptarget/test/api/assert.c rename to offload/test/api/assert.c diff --git a/openmp/libomptarget/test/api/is_initial_device.c b/offload/test/api/is_initial_device.c similarity index 100% rename from openmp/libomptarget/test/api/is_initial_device.c rename to offload/test/api/is_initial_device.c diff --git a/openmp/libomptarget/test/api/omp_device_managed_memory.c b/offload/test/api/omp_device_managed_memory.c similarity index 100% rename from openmp/libomptarget/test/api/omp_device_managed_memory.c rename to offload/test/api/omp_device_managed_memory.c diff --git a/openmp/libomptarget/test/api/omp_device_managed_memory_alloc.c b/offload/test/api/omp_device_managed_memory_alloc.c similarity index 100% rename from openmp/libomptarget/test/api/omp_device_managed_memory_alloc.c rename to offload/test/api/omp_device_managed_memory_alloc.c diff --git a/openmp/libomptarget/test/api/omp_device_memory.c b/offload/test/api/omp_device_memory.c similarity index 100% rename from openmp/libomptarget/test/api/omp_device_memory.c rename to offload/test/api/omp_device_memory.c diff --git a/openmp/libomptarget/test/api/omp_dynamic_shared_memory.c b/offload/test/api/omp_dynamic_shared_memory.c similarity index 100% rename from openmp/libomptarget/test/api/omp_dynamic_shared_memory.c rename to offload/test/api/omp_dynamic_shared_memory.c diff --git a/openmp/libomptarget/test/api/omp_dynamic_shared_memory_amdgpu.c b/offload/test/api/omp_dynamic_shared_memory_amdgpu.c similarity index 100% rename from openmp/libomptarget/test/api/omp_dynamic_shared_memory_amdgpu.c rename to offload/test/api/omp_dynamic_shared_memory_amdgpu.c diff --git a/openmp/libomptarget/test/api/omp_dynamic_shared_memory_mixed.inc b/offload/test/api/omp_dynamic_shared_memory_mixed.inc similarity index 100% rename from openmp/libomptarget/test/api/omp_dynamic_shared_memory_mixed.inc rename to offload/test/api/omp_dynamic_shared_memory_mixed.inc diff --git a/openmp/libomptarget/test/api/omp_dynamic_shared_memory_mixed_amdgpu.c b/offload/test/api/omp_dynamic_shared_memory_mixed_amdgpu.c similarity index 100% rename from openmp/libomptarget/test/api/omp_dynamic_shared_memory_mixed_amdgpu.c rename to offload/test/api/omp_dynamic_shared_memory_mixed_amdgpu.c diff --git a/openmp/libomptarget/test/api/omp_dynamic_shared_memory_mixed_nvptx.c b/offload/test/api/omp_dynamic_shared_memory_mixed_nvptx.c similarity index 100% rename from openmp/libomptarget/test/api/omp_dynamic_shared_memory_mixed_nvptx.c rename to offload/test/api/omp_dynamic_shared_memory_mixed_nvptx.c diff --git a/openmp/libomptarget/test/api/omp_env_vars.c b/offload/test/api/omp_env_vars.c similarity index 100% rename from openmp/libomptarget/test/api/omp_env_vars.c rename to offload/test/api/omp_env_vars.c diff --git a/openmp/libomptarget/test/api/omp_get_device_num.c b/offload/test/api/omp_get_device_num.c similarity index 100% rename from openmp/libomptarget/test/api/omp_get_device_num.c rename to offload/test/api/omp_get_device_num.c diff --git a/openmp/libomptarget/test/api/omp_get_mapped_ptr.c b/offload/test/api/omp_get_mapped_ptr.c similarity index 100% rename from openmp/libomptarget/test/api/omp_get_mapped_ptr.c rename to offload/test/api/omp_get_mapped_ptr.c diff --git a/openmp/libomptarget/test/api/omp_get_num_devices.c b/offload/test/api/omp_get_num_devices.c similarity index 100% rename from openmp/libomptarget/test/api/omp_get_num_devices.c rename to offload/test/api/omp_get_num_devices.c diff --git a/openmp/libomptarget/test/api/omp_get_num_devices_with_empty_target.c b/offload/test/api/omp_get_num_devices_with_empty_target.c similarity index 100% rename from openmp/libomptarget/test/api/omp_get_num_devices_with_empty_target.c rename to offload/test/api/omp_get_num_devices_with_empty_target.c diff --git a/openmp/libomptarget/test/api/omp_get_num_procs.c b/offload/test/api/omp_get_num_procs.c similarity index 100% rename from openmp/libomptarget/test/api/omp_get_num_procs.c rename to offload/test/api/omp_get_num_procs.c diff --git a/openmp/libomptarget/test/api/omp_host_pinned_memory.c b/offload/test/api/omp_host_pinned_memory.c similarity index 100% rename from openmp/libomptarget/test/api/omp_host_pinned_memory.c rename to offload/test/api/omp_host_pinned_memory.c diff --git a/openmp/libomptarget/test/api/omp_host_pinned_memory_alloc.c b/offload/test/api/omp_host_pinned_memory_alloc.c similarity index 100% rename from openmp/libomptarget/test/api/omp_host_pinned_memory_alloc.c rename to offload/test/api/omp_host_pinned_memory_alloc.c diff --git a/openmp/libomptarget/test/api/omp_indirect_call.c b/offload/test/api/omp_indirect_call.c similarity index 100% rename from openmp/libomptarget/test/api/omp_indirect_call.c rename to offload/test/api/omp_indirect_call.c diff --git a/openmp/libomptarget/test/api/omp_target_memcpy_async1.c b/offload/test/api/omp_target_memcpy_async1.c similarity index 100% rename from openmp/libomptarget/test/api/omp_target_memcpy_async1.c rename to offload/test/api/omp_target_memcpy_async1.c diff --git a/openmp/libomptarget/test/api/omp_target_memcpy_async2.c b/offload/test/api/omp_target_memcpy_async2.c similarity index 100% rename from openmp/libomptarget/test/api/omp_target_memcpy_async2.c rename to offload/test/api/omp_target_memcpy_async2.c diff --git a/openmp/libomptarget/test/api/omp_target_memcpy_rect_async1.c b/offload/test/api/omp_target_memcpy_rect_async1.c similarity index 100% rename from openmp/libomptarget/test/api/omp_target_memcpy_rect_async1.c rename to offload/test/api/omp_target_memcpy_rect_async1.c diff --git a/openmp/libomptarget/test/api/omp_target_memcpy_rect_async2.c b/offload/test/api/omp_target_memcpy_rect_async2.c similarity index 100% rename from openmp/libomptarget/test/api/omp_target_memcpy_rect_async2.c rename to offload/test/api/omp_target_memcpy_rect_async2.c diff --git a/openmp/libomptarget/test/api/omp_target_memset.c b/offload/test/api/omp_target_memset.c similarity index 100% rename from openmp/libomptarget/test/api/omp_target_memset.c rename to offload/test/api/omp_target_memset.c diff --git a/openmp/libomptarget/test/api/ompx_3d.c b/offload/test/api/ompx_3d.c similarity index 100% rename from openmp/libomptarget/test/api/ompx_3d.c rename to offload/test/api/ompx_3d.c diff --git a/openmp/libomptarget/test/api/ompx_3d.cpp b/offload/test/api/ompx_3d.cpp similarity index 100% rename from openmp/libomptarget/test/api/ompx_3d.cpp rename to offload/test/api/ompx_3d.cpp diff --git a/openmp/libomptarget/test/api/ompx_sync.c b/offload/test/api/ompx_sync.c similarity index 100% rename from openmp/libomptarget/test/api/ompx_sync.c rename to offload/test/api/ompx_sync.c diff --git a/openmp/libomptarget/test/api/ompx_sync.cpp b/offload/test/api/ompx_sync.cpp similarity index 100% rename from openmp/libomptarget/test/api/ompx_sync.cpp rename to offload/test/api/ompx_sync.cpp diff --git a/openmp/libomptarget/test/env/base_ptr_ref_count.c b/offload/test/env/base_ptr_ref_count.c similarity index 100% rename from openmp/libomptarget/test/env/base_ptr_ref_count.c rename to offload/test/env/base_ptr_ref_count.c diff --git a/openmp/libomptarget/test/env/omp_target_debug.c b/offload/test/env/omp_target_debug.c similarity index 100% rename from openmp/libomptarget/test/env/omp_target_debug.c rename to offload/test/env/omp_target_debug.c diff --git a/openmp/libomptarget/test/jit/empty_kernel.inc b/offload/test/jit/empty_kernel.inc similarity index 100% rename from openmp/libomptarget/test/jit/empty_kernel.inc rename to offload/test/jit/empty_kernel.inc diff --git a/openmp/libomptarget/test/jit/empty_kernel_lvl1.c b/offload/test/jit/empty_kernel_lvl1.c similarity index 100% rename from openmp/libomptarget/test/jit/empty_kernel_lvl1.c rename to offload/test/jit/empty_kernel_lvl1.c diff --git a/openmp/libomptarget/test/jit/empty_kernel_lvl2.c b/offload/test/jit/empty_kernel_lvl2.c similarity index 100% rename from openmp/libomptarget/test/jit/empty_kernel_lvl2.c rename to offload/test/jit/empty_kernel_lvl2.c diff --git a/openmp/libomptarget/test/jit/type_punning.c b/offload/test/jit/type_punning.c similarity index 100% rename from openmp/libomptarget/test/jit/type_punning.c rename to offload/test/jit/type_punning.c diff --git a/openmp/libomptarget/test/libc/assert.c b/offload/test/libc/assert.c similarity index 100% rename from openmp/libomptarget/test/libc/assert.c rename to offload/test/libc/assert.c diff --git a/openmp/libomptarget/test/libc/fwrite.c b/offload/test/libc/fwrite.c similarity index 100% rename from openmp/libomptarget/test/libc/fwrite.c rename to offload/test/libc/fwrite.c diff --git a/openmp/libomptarget/test/libc/global_ctor_dtor.cpp b/offload/test/libc/global_ctor_dtor.cpp similarity index 100% rename from openmp/libomptarget/test/libc/global_ctor_dtor.cpp rename to offload/test/libc/global_ctor_dtor.cpp diff --git a/openmp/libomptarget/test/libc/host_call.c b/offload/test/libc/host_call.c similarity index 100% rename from openmp/libomptarget/test/libc/host_call.c rename to offload/test/libc/host_call.c diff --git a/openmp/libomptarget/test/libc/malloc.c b/offload/test/libc/malloc.c similarity index 100% rename from openmp/libomptarget/test/libc/malloc.c rename to offload/test/libc/malloc.c diff --git a/openmp/libomptarget/test/libc/puts.c b/offload/test/libc/puts.c similarity index 100% rename from openmp/libomptarget/test/libc/puts.c rename to offload/test/libc/puts.c diff --git a/openmp/libomptarget/test/lit.cfg b/offload/test/lit.cfg similarity index 100% rename from openmp/libomptarget/test/lit.cfg rename to offload/test/lit.cfg diff --git a/openmp/libomptarget/test/lit.site.cfg.in b/offload/test/lit.site.cfg.in similarity index 100% rename from openmp/libomptarget/test/lit.site.cfg.in rename to offload/test/lit.site.cfg.in diff --git a/openmp/libomptarget/test/mapping/alloc_fail.c b/offload/test/mapping/alloc_fail.c similarity index 100% rename from openmp/libomptarget/test/mapping/alloc_fail.c rename to offload/test/mapping/alloc_fail.c diff --git a/openmp/libomptarget/test/mapping/array_section_implicit_capture.c b/offload/test/mapping/array_section_implicit_capture.c similarity index 100% rename from openmp/libomptarget/test/mapping/array_section_implicit_capture.c rename to offload/test/mapping/array_section_implicit_capture.c diff --git a/openmp/libomptarget/test/mapping/array_section_use_device_ptr.c b/offload/test/mapping/array_section_use_device_ptr.c similarity index 100% rename from openmp/libomptarget/test/mapping/array_section_use_device_ptr.c rename to offload/test/mapping/array_section_use_device_ptr.c diff --git a/openmp/libomptarget/test/mapping/auto_zero_copy.cpp b/offload/test/mapping/auto_zero_copy.cpp similarity index 100% rename from openmp/libomptarget/test/mapping/auto_zero_copy.cpp rename to offload/test/mapping/auto_zero_copy.cpp diff --git a/openmp/libomptarget/test/mapping/auto_zero_copy_apu.cpp b/offload/test/mapping/auto_zero_copy_apu.cpp similarity index 100% rename from openmp/libomptarget/test/mapping/auto_zero_copy_apu.cpp rename to offload/test/mapping/auto_zero_copy_apu.cpp diff --git a/openmp/libomptarget/test/mapping/auto_zero_copy_globals.cpp b/offload/test/mapping/auto_zero_copy_globals.cpp similarity index 100% rename from openmp/libomptarget/test/mapping/auto_zero_copy_globals.cpp rename to offload/test/mapping/auto_zero_copy_globals.cpp diff --git a/openmp/libomptarget/test/mapping/data_absent_at_exit.c b/offload/test/mapping/data_absent_at_exit.c similarity index 100% rename from openmp/libomptarget/test/mapping/data_absent_at_exit.c rename to offload/test/mapping/data_absent_at_exit.c diff --git a/openmp/libomptarget/test/mapping/data_member_ref.cpp b/offload/test/mapping/data_member_ref.cpp similarity index 100% rename from openmp/libomptarget/test/mapping/data_member_ref.cpp rename to offload/test/mapping/data_member_ref.cpp diff --git a/openmp/libomptarget/test/mapping/declare_mapper_api.cpp b/offload/test/mapping/declare_mapper_api.cpp similarity index 100% rename from openmp/libomptarget/test/mapping/declare_mapper_api.cpp rename to offload/test/mapping/declare_mapper_api.cpp diff --git a/openmp/libomptarget/test/mapping/declare_mapper_nested_default_mappers.cpp b/offload/test/mapping/declare_mapper_nested_default_mappers.cpp similarity index 100% rename from openmp/libomptarget/test/mapping/declare_mapper_nested_default_mappers.cpp rename to offload/test/mapping/declare_mapper_nested_default_mappers.cpp diff --git a/openmp/libomptarget/test/mapping/declare_mapper_nested_default_mappers_array.cpp b/offload/test/mapping/declare_mapper_nested_default_mappers_array.cpp similarity index 100% rename from openmp/libomptarget/test/mapping/declare_mapper_nested_default_mappers_array.cpp rename to offload/test/mapping/declare_mapper_nested_default_mappers_array.cpp diff --git a/openmp/libomptarget/test/mapping/declare_mapper_nested_default_mappers_array_subscript.cpp b/offload/test/mapping/declare_mapper_nested_default_mappers_array_subscript.cpp similarity index 100% rename from openmp/libomptarget/test/mapping/declare_mapper_nested_default_mappers_array_subscript.cpp rename to offload/test/mapping/declare_mapper_nested_default_mappers_array_subscript.cpp diff --git a/openmp/libomptarget/test/mapping/declare_mapper_nested_default_mappers_complex_structure.cpp b/offload/test/mapping/declare_mapper_nested_default_mappers_complex_structure.cpp similarity index 100% rename from openmp/libomptarget/test/mapping/declare_mapper_nested_default_mappers_complex_structure.cpp rename to offload/test/mapping/declare_mapper_nested_default_mappers_complex_structure.cpp diff --git a/openmp/libomptarget/test/mapping/declare_mapper_nested_default_mappers_ptr_subscript.cpp b/offload/test/mapping/declare_mapper_nested_default_mappers_ptr_subscript.cpp similarity index 100% rename from openmp/libomptarget/test/mapping/declare_mapper_nested_default_mappers_ptr_subscript.cpp rename to offload/test/mapping/declare_mapper_nested_default_mappers_ptr_subscript.cpp diff --git a/openmp/libomptarget/test/mapping/declare_mapper_nested_default_mappers_var.cpp b/offload/test/mapping/declare_mapper_nested_default_mappers_var.cpp similarity index 100% rename from openmp/libomptarget/test/mapping/declare_mapper_nested_default_mappers_var.cpp rename to offload/test/mapping/declare_mapper_nested_default_mappers_var.cpp diff --git a/openmp/libomptarget/test/mapping/declare_mapper_nested_mappers.cpp b/offload/test/mapping/declare_mapper_nested_mappers.cpp similarity index 100% rename from openmp/libomptarget/test/mapping/declare_mapper_nested_mappers.cpp rename to offload/test/mapping/declare_mapper_nested_mappers.cpp diff --git a/openmp/libomptarget/test/mapping/declare_mapper_target.cpp b/offload/test/mapping/declare_mapper_target.cpp similarity index 100% rename from openmp/libomptarget/test/mapping/declare_mapper_target.cpp rename to offload/test/mapping/declare_mapper_target.cpp diff --git a/openmp/libomptarget/test/mapping/declare_mapper_target_data.cpp b/offload/test/mapping/declare_mapper_target_data.cpp similarity index 100% rename from openmp/libomptarget/test/mapping/declare_mapper_target_data.cpp rename to offload/test/mapping/declare_mapper_target_data.cpp diff --git a/openmp/libomptarget/test/mapping/declare_mapper_target_data_enter_exit.cpp b/offload/test/mapping/declare_mapper_target_data_enter_exit.cpp similarity index 100% rename from openmp/libomptarget/test/mapping/declare_mapper_target_data_enter_exit.cpp rename to offload/test/mapping/declare_mapper_target_data_enter_exit.cpp diff --git a/openmp/libomptarget/test/mapping/declare_mapper_target_update.cpp b/offload/test/mapping/declare_mapper_target_update.cpp similarity index 100% rename from openmp/libomptarget/test/mapping/declare_mapper_target_update.cpp rename to offload/test/mapping/declare_mapper_target_update.cpp diff --git a/openmp/libomptarget/test/mapping/delete_inf_refcount.c b/offload/test/mapping/delete_inf_refcount.c similarity index 100% rename from openmp/libomptarget/test/mapping/delete_inf_refcount.c rename to offload/test/mapping/delete_inf_refcount.c diff --git a/openmp/libomptarget/test/mapping/device_ptr_update.c b/offload/test/mapping/device_ptr_update.c similarity index 100% rename from openmp/libomptarget/test/mapping/device_ptr_update.c rename to offload/test/mapping/device_ptr_update.c diff --git a/openmp/libomptarget/test/mapping/firstprivate_aligned.cpp b/offload/test/mapping/firstprivate_aligned.cpp similarity index 100% rename from openmp/libomptarget/test/mapping/firstprivate_aligned.cpp rename to offload/test/mapping/firstprivate_aligned.cpp diff --git a/openmp/libomptarget/test/mapping/has_device_addr.cpp b/offload/test/mapping/has_device_addr.cpp similarity index 100% rename from openmp/libomptarget/test/mapping/has_device_addr.cpp rename to offload/test/mapping/has_device_addr.cpp diff --git a/openmp/libomptarget/test/mapping/implicit_device_ptr.c b/offload/test/mapping/implicit_device_ptr.c similarity index 100% rename from openmp/libomptarget/test/mapping/implicit_device_ptr.c rename to offload/test/mapping/implicit_device_ptr.c diff --git a/openmp/libomptarget/test/mapping/is_device_ptr.cpp b/offload/test/mapping/is_device_ptr.cpp similarity index 100% rename from openmp/libomptarget/test/mapping/is_device_ptr.cpp rename to offload/test/mapping/is_device_ptr.cpp diff --git a/openmp/libomptarget/test/mapping/lambda_by_value.cpp b/offload/test/mapping/lambda_by_value.cpp similarity index 100% rename from openmp/libomptarget/test/mapping/lambda_by_value.cpp rename to offload/test/mapping/lambda_by_value.cpp diff --git a/openmp/libomptarget/test/mapping/lambda_mapping.cpp b/offload/test/mapping/lambda_mapping.cpp similarity index 100% rename from openmp/libomptarget/test/mapping/lambda_mapping.cpp rename to offload/test/mapping/lambda_mapping.cpp diff --git a/openmp/libomptarget/test/mapping/low_alignment.c b/offload/test/mapping/low_alignment.c similarity index 100% rename from openmp/libomptarget/test/mapping/low_alignment.c rename to offload/test/mapping/low_alignment.c diff --git a/openmp/libomptarget/test/mapping/map_back_race.cpp b/offload/test/mapping/map_back_race.cpp similarity index 100% rename from openmp/libomptarget/test/mapping/map_back_race.cpp rename to offload/test/mapping/map_back_race.cpp diff --git a/openmp/libomptarget/test/mapping/ompx_hold/omp_target_disassociate_ptr.c b/offload/test/mapping/ompx_hold/omp_target_disassociate_ptr.c similarity index 100% rename from openmp/libomptarget/test/mapping/ompx_hold/omp_target_disassociate_ptr.c rename to offload/test/mapping/ompx_hold/omp_target_disassociate_ptr.c diff --git a/openmp/libomptarget/test/mapping/ompx_hold/struct.c b/offload/test/mapping/ompx_hold/struct.c similarity index 100% rename from openmp/libomptarget/test/mapping/ompx_hold/struct.c rename to offload/test/mapping/ompx_hold/struct.c diff --git a/openmp/libomptarget/test/mapping/ompx_hold/target-data.c b/offload/test/mapping/ompx_hold/target-data.c similarity index 100% rename from openmp/libomptarget/test/mapping/ompx_hold/target-data.c rename to offload/test/mapping/ompx_hold/target-data.c diff --git a/openmp/libomptarget/test/mapping/ompx_hold/target.c b/offload/test/mapping/ompx_hold/target.c similarity index 100% rename from openmp/libomptarget/test/mapping/ompx_hold/target.c rename to offload/test/mapping/ompx_hold/target.c diff --git a/openmp/libomptarget/test/mapping/padding_not_mapped.c b/offload/test/mapping/padding_not_mapped.c similarity index 100% rename from openmp/libomptarget/test/mapping/padding_not_mapped.c rename to offload/test/mapping/padding_not_mapped.c diff --git a/openmp/libomptarget/test/mapping/power_of_two_alignment.c b/offload/test/mapping/power_of_two_alignment.c similarity index 100% rename from openmp/libomptarget/test/mapping/power_of_two_alignment.c rename to offload/test/mapping/power_of_two_alignment.c diff --git a/openmp/libomptarget/test/mapping/pr38704.c b/offload/test/mapping/pr38704.c similarity index 100% rename from openmp/libomptarget/test/mapping/pr38704.c rename to offload/test/mapping/pr38704.c diff --git a/openmp/libomptarget/test/mapping/prelock.cpp b/offload/test/mapping/prelock.cpp similarity index 100% rename from openmp/libomptarget/test/mapping/prelock.cpp rename to offload/test/mapping/prelock.cpp diff --git a/openmp/libomptarget/test/mapping/present/target.c b/offload/test/mapping/present/target.c similarity index 100% rename from openmp/libomptarget/test/mapping/present/target.c rename to offload/test/mapping/present/target.c diff --git a/openmp/libomptarget/test/mapping/present/target_array_extension.c b/offload/test/mapping/present/target_array_extension.c similarity index 100% rename from openmp/libomptarget/test/mapping/present/target_array_extension.c rename to offload/test/mapping/present/target_array_extension.c diff --git a/openmp/libomptarget/test/mapping/present/target_data.c b/offload/test/mapping/present/target_data.c similarity index 100% rename from openmp/libomptarget/test/mapping/present/target_data.c rename to offload/test/mapping/present/target_data.c diff --git a/openmp/libomptarget/test/mapping/present/target_data_array_extension.c b/offload/test/mapping/present/target_data_array_extension.c similarity index 100% rename from openmp/libomptarget/test/mapping/present/target_data_array_extension.c rename to offload/test/mapping/present/target_data_array_extension.c diff --git a/openmp/libomptarget/test/mapping/present/target_data_at_exit.c b/offload/test/mapping/present/target_data_at_exit.c similarity index 100% rename from openmp/libomptarget/test/mapping/present/target_data_at_exit.c rename to offload/test/mapping/present/target_data_at_exit.c diff --git a/openmp/libomptarget/test/mapping/present/target_enter_data.c b/offload/test/mapping/present/target_enter_data.c similarity index 100% rename from openmp/libomptarget/test/mapping/present/target_enter_data.c rename to offload/test/mapping/present/target_enter_data.c diff --git a/openmp/libomptarget/test/mapping/present/target_exit_data_delete.c b/offload/test/mapping/present/target_exit_data_delete.c similarity index 100% rename from openmp/libomptarget/test/mapping/present/target_exit_data_delete.c rename to offload/test/mapping/present/target_exit_data_delete.c diff --git a/openmp/libomptarget/test/mapping/present/target_exit_data_release.c b/offload/test/mapping/present/target_exit_data_release.c similarity index 100% rename from openmp/libomptarget/test/mapping/present/target_exit_data_release.c rename to offload/test/mapping/present/target_exit_data_release.c diff --git a/openmp/libomptarget/test/mapping/present/target_update.c b/offload/test/mapping/present/target_update.c similarity index 100% rename from openmp/libomptarget/test/mapping/present/target_update.c rename to offload/test/mapping/present/target_update.c diff --git a/openmp/libomptarget/test/mapping/present/target_update_array_extension.c b/offload/test/mapping/present/target_update_array_extension.c similarity index 100% rename from openmp/libomptarget/test/mapping/present/target_update_array_extension.c rename to offload/test/mapping/present/target_update_array_extension.c diff --git a/openmp/libomptarget/test/mapping/present/unified_shared_memory.c b/offload/test/mapping/present/unified_shared_memory.c similarity index 100% rename from openmp/libomptarget/test/mapping/present/unified_shared_memory.c rename to offload/test/mapping/present/unified_shared_memory.c diff --git a/openmp/libomptarget/test/mapping/present/zero_length_array_section.c b/offload/test/mapping/present/zero_length_array_section.c similarity index 100% rename from openmp/libomptarget/test/mapping/present/zero_length_array_section.c rename to offload/test/mapping/present/zero_length_array_section.c diff --git a/openmp/libomptarget/test/mapping/present/zero_length_array_section_exit.c b/offload/test/mapping/present/zero_length_array_section_exit.c similarity index 100% rename from openmp/libomptarget/test/mapping/present/zero_length_array_section_exit.c rename to offload/test/mapping/present/zero_length_array_section_exit.c diff --git a/openmp/libomptarget/test/mapping/private_mapping.c b/offload/test/mapping/private_mapping.c similarity index 100% rename from openmp/libomptarget/test/mapping/private_mapping.c rename to offload/test/mapping/private_mapping.c diff --git a/openmp/libomptarget/test/mapping/ptr_and_obj_motion.c b/offload/test/mapping/ptr_and_obj_motion.c similarity index 100% rename from openmp/libomptarget/test/mapping/ptr_and_obj_motion.c rename to offload/test/mapping/ptr_and_obj_motion.c diff --git a/openmp/libomptarget/test/mapping/reduction_implicit_map.cpp b/offload/test/mapping/reduction_implicit_map.cpp similarity index 100% rename from openmp/libomptarget/test/mapping/reduction_implicit_map.cpp rename to offload/test/mapping/reduction_implicit_map.cpp diff --git a/openmp/libomptarget/test/mapping/target_data_array_extension_at_exit.c b/offload/test/mapping/target_data_array_extension_at_exit.c similarity index 100% rename from openmp/libomptarget/test/mapping/target_data_array_extension_at_exit.c rename to offload/test/mapping/target_data_array_extension_at_exit.c diff --git a/openmp/libomptarget/test/mapping/target_derefence_array_pointrs.cpp b/offload/test/mapping/target_derefence_array_pointrs.cpp similarity index 100% rename from openmp/libomptarget/test/mapping/target_derefence_array_pointrs.cpp rename to offload/test/mapping/target_derefence_array_pointrs.cpp diff --git a/openmp/libomptarget/test/mapping/target_has_device_addr.c b/offload/test/mapping/target_has_device_addr.c similarity index 100% rename from openmp/libomptarget/test/mapping/target_has_device_addr.c rename to offload/test/mapping/target_has_device_addr.c diff --git a/openmp/libomptarget/test/mapping/target_implicit_partial_map.c b/offload/test/mapping/target_implicit_partial_map.c similarity index 100% rename from openmp/libomptarget/test/mapping/target_implicit_partial_map.c rename to offload/test/mapping/target_implicit_partial_map.c diff --git a/openmp/libomptarget/test/mapping/target_map_for_member_data.cpp b/offload/test/mapping/target_map_for_member_data.cpp similarity index 100% rename from openmp/libomptarget/test/mapping/target_map_for_member_data.cpp rename to offload/test/mapping/target_map_for_member_data.cpp diff --git a/openmp/libomptarget/test/mapping/target_pointers_members_map.cpp b/offload/test/mapping/target_pointers_members_map.cpp similarity index 100% rename from openmp/libomptarget/test/mapping/target_pointers_members_map.cpp rename to offload/test/mapping/target_pointers_members_map.cpp diff --git a/openmp/libomptarget/test/mapping/target_update_array_extension.c b/offload/test/mapping/target_update_array_extension.c similarity index 100% rename from openmp/libomptarget/test/mapping/target_update_array_extension.c rename to offload/test/mapping/target_update_array_extension.c diff --git a/openmp/libomptarget/test/mapping/target_use_device_addr.c b/offload/test/mapping/target_use_device_addr.c similarity index 100% rename from openmp/libomptarget/test/mapping/target_use_device_addr.c rename to offload/test/mapping/target_use_device_addr.c diff --git a/openmp/libomptarget/test/mapping/target_uses_allocator.c b/offload/test/mapping/target_uses_allocator.c similarity index 100% rename from openmp/libomptarget/test/mapping/target_uses_allocator.c rename to offload/test/mapping/target_uses_allocator.c diff --git a/openmp/libomptarget/test/mapping/target_wrong_use_device_addr.c b/offload/test/mapping/target_wrong_use_device_addr.c similarity index 100% rename from openmp/libomptarget/test/mapping/target_wrong_use_device_addr.c rename to offload/test/mapping/target_wrong_use_device_addr.c diff --git a/openmp/libomptarget/test/offloading/assert.cpp b/offload/test/offloading/assert.cpp similarity index 100% rename from openmp/libomptarget/test/offloading/assert.cpp rename to offload/test/offloading/assert.cpp diff --git a/openmp/libomptarget/test/offloading/atomic-compare-signedness.c b/offload/test/offloading/atomic-compare-signedness.c similarity index 100% rename from openmp/libomptarget/test/offloading/atomic-compare-signedness.c rename to offload/test/offloading/atomic-compare-signedness.c diff --git a/openmp/libomptarget/test/offloading/back2back_distribute.c b/offload/test/offloading/back2back_distribute.c similarity index 100% rename from openmp/libomptarget/test/offloading/back2back_distribute.c rename to offload/test/offloading/back2back_distribute.c diff --git a/openmp/libomptarget/test/offloading/barrier_fence.c b/offload/test/offloading/barrier_fence.c similarity index 100% rename from openmp/libomptarget/test/offloading/barrier_fence.c rename to offload/test/offloading/barrier_fence.c diff --git a/openmp/libomptarget/test/offloading/bug47654.cpp b/offload/test/offloading/bug47654.cpp similarity index 100% rename from openmp/libomptarget/test/offloading/bug47654.cpp rename to offload/test/offloading/bug47654.cpp diff --git a/openmp/libomptarget/test/offloading/bug49021.cpp b/offload/test/offloading/bug49021.cpp similarity index 100% rename from openmp/libomptarget/test/offloading/bug49021.cpp rename to offload/test/offloading/bug49021.cpp diff --git a/openmp/libomptarget/test/offloading/bug49334.cpp b/offload/test/offloading/bug49334.cpp similarity index 100% rename from openmp/libomptarget/test/offloading/bug49334.cpp rename to offload/test/offloading/bug49334.cpp diff --git a/openmp/libomptarget/test/offloading/bug49779.cpp b/offload/test/offloading/bug49779.cpp similarity index 100% rename from openmp/libomptarget/test/offloading/bug49779.cpp rename to offload/test/offloading/bug49779.cpp diff --git a/openmp/libomptarget/test/offloading/bug50022.cpp b/offload/test/offloading/bug50022.cpp similarity index 100% rename from openmp/libomptarget/test/offloading/bug50022.cpp rename to offload/test/offloading/bug50022.cpp diff --git a/openmp/libomptarget/test/offloading/bug51781.c b/offload/test/offloading/bug51781.c similarity index 100% rename from openmp/libomptarget/test/offloading/bug51781.c rename to offload/test/offloading/bug51781.c diff --git a/openmp/libomptarget/test/offloading/bug51982.c b/offload/test/offloading/bug51982.c similarity index 100% rename from openmp/libomptarget/test/offloading/bug51982.c rename to offload/test/offloading/bug51982.c diff --git a/openmp/libomptarget/test/offloading/bug53727.cpp b/offload/test/offloading/bug53727.cpp similarity index 100% rename from openmp/libomptarget/test/offloading/bug53727.cpp rename to offload/test/offloading/bug53727.cpp diff --git a/openmp/libomptarget/test/offloading/bug64959.c b/offload/test/offloading/bug64959.c similarity index 100% rename from openmp/libomptarget/test/offloading/bug64959.c rename to offload/test/offloading/bug64959.c diff --git a/openmp/libomptarget/test/offloading/bug64959_compile_only.c b/offload/test/offloading/bug64959_compile_only.c similarity index 100% rename from openmp/libomptarget/test/offloading/bug64959_compile_only.c rename to offload/test/offloading/bug64959_compile_only.c diff --git a/openmp/libomptarget/test/offloading/bug74582.c b/offload/test/offloading/bug74582.c similarity index 100% rename from openmp/libomptarget/test/offloading/bug74582.c rename to offload/test/offloading/bug74582.c diff --git a/openmp/libomptarget/test/offloading/complex_reduction.cpp b/offload/test/offloading/complex_reduction.cpp similarity index 100% rename from openmp/libomptarget/test/offloading/complex_reduction.cpp rename to offload/test/offloading/complex_reduction.cpp diff --git a/openmp/libomptarget/test/offloading/ctor_dtor.cpp b/offload/test/offloading/ctor_dtor.cpp similarity index 100% rename from openmp/libomptarget/test/offloading/ctor_dtor.cpp rename to offload/test/offloading/ctor_dtor.cpp diff --git a/openmp/libomptarget/test/offloading/cuda_no_devices.c b/offload/test/offloading/cuda_no_devices.c similarity index 100% rename from openmp/libomptarget/test/offloading/cuda_no_devices.c rename to offload/test/offloading/cuda_no_devices.c diff --git a/openmp/libomptarget/test/offloading/d2d_memcpy.c b/offload/test/offloading/d2d_memcpy.c similarity index 100% rename from openmp/libomptarget/test/offloading/d2d_memcpy.c rename to offload/test/offloading/d2d_memcpy.c diff --git a/openmp/libomptarget/test/offloading/d2d_memcpy_sync.c b/offload/test/offloading/d2d_memcpy_sync.c similarity index 100% rename from openmp/libomptarget/test/offloading/d2d_memcpy_sync.c rename to offload/test/offloading/d2d_memcpy_sync.c diff --git a/openmp/libomptarget/test/offloading/default_thread_limit.c b/offload/test/offloading/default_thread_limit.c similarity index 100% rename from openmp/libomptarget/test/offloading/default_thread_limit.c rename to offload/test/offloading/default_thread_limit.c diff --git a/openmp/libomptarget/test/offloading/dynamic_module.c b/offload/test/offloading/dynamic_module.c similarity index 100% rename from openmp/libomptarget/test/offloading/dynamic_module.c rename to offload/test/offloading/dynamic_module.c diff --git a/openmp/libomptarget/test/offloading/dynamic_module_load.c b/offload/test/offloading/dynamic_module_load.c similarity index 100% rename from openmp/libomptarget/test/offloading/dynamic_module_load.c rename to offload/test/offloading/dynamic_module_load.c diff --git a/openmp/libomptarget/test/offloading/extern.c b/offload/test/offloading/extern.c similarity index 100% rename from openmp/libomptarget/test/offloading/extern.c rename to offload/test/offloading/extern.c diff --git a/openmp/libomptarget/test/offloading/force-usm.cpp b/offload/test/offloading/force-usm.cpp similarity index 100% rename from openmp/libomptarget/test/offloading/force-usm.cpp rename to offload/test/offloading/force-usm.cpp diff --git a/openmp/libomptarget/test/offloading/fortran/basic-target-parallel-do.f90 b/offload/test/offloading/fortran/basic-target-parallel-do.f90 similarity index 100% rename from openmp/libomptarget/test/offloading/fortran/basic-target-parallel-do.f90 rename to offload/test/offloading/fortran/basic-target-parallel-do.f90 diff --git a/openmp/libomptarget/test/offloading/fortran/basic-target-parallel-region.f90 b/offload/test/offloading/fortran/basic-target-parallel-region.f90 similarity index 100% rename from openmp/libomptarget/test/offloading/fortran/basic-target-parallel-region.f90 rename to offload/test/offloading/fortran/basic-target-parallel-region.f90 diff --git a/openmp/libomptarget/test/offloading/fortran/basic-target-region-1D-array-section.f90 b/offload/test/offloading/fortran/basic-target-region-1D-array-section.f90 similarity index 100% rename from openmp/libomptarget/test/offloading/fortran/basic-target-region-1D-array-section.f90 rename to offload/test/offloading/fortran/basic-target-region-1D-array-section.f90 diff --git a/openmp/libomptarget/test/offloading/fortran/basic-target-region-3D-array-section.f90 b/offload/test/offloading/fortran/basic-target-region-3D-array-section.f90 similarity index 100% rename from openmp/libomptarget/test/offloading/fortran/basic-target-region-3D-array-section.f90 rename to offload/test/offloading/fortran/basic-target-region-3D-array-section.f90 diff --git a/openmp/libomptarget/test/offloading/fortran/basic-target-region-3D-array.f90 b/offload/test/offloading/fortran/basic-target-region-3D-array.f90 similarity index 100% rename from openmp/libomptarget/test/offloading/fortran/basic-target-region-3D-array.f90 rename to offload/test/offloading/fortran/basic-target-region-3D-array.f90 diff --git a/openmp/libomptarget/test/offloading/fortran/basic_array.c b/offload/test/offloading/fortran/basic_array.c similarity index 100% rename from openmp/libomptarget/test/offloading/fortran/basic_array.c rename to offload/test/offloading/fortran/basic_array.c diff --git a/openmp/libomptarget/test/offloading/fortran/basic_target_region.f90 b/offload/test/offloading/fortran/basic_target_region.f90 similarity index 100% rename from openmp/libomptarget/test/offloading/fortran/basic_target_region.f90 rename to offload/test/offloading/fortran/basic_target_region.f90 diff --git a/openmp/libomptarget/test/offloading/fortran/constant-arr-index.f90 b/offload/test/offloading/fortran/constant-arr-index.f90 similarity index 100% rename from openmp/libomptarget/test/offloading/fortran/constant-arr-index.f90 rename to offload/test/offloading/fortran/constant-arr-index.f90 diff --git a/openmp/libomptarget/test/offloading/fortran/declare-target-vars-in-target-region.f90 b/offload/test/offloading/fortran/declare-target-vars-in-target-region.f90 similarity index 100% rename from openmp/libomptarget/test/offloading/fortran/declare-target-vars-in-target-region.f90 rename to offload/test/offloading/fortran/declare-target-vars-in-target-region.f90 diff --git a/openmp/libomptarget/test/offloading/fortran/double-target-call-with-declare-target.f90 b/offload/test/offloading/fortran/double-target-call-with-declare-target.f90 similarity index 100% rename from openmp/libomptarget/test/offloading/fortran/double-target-call-with-declare-target.f90 rename to offload/test/offloading/fortran/double-target-call-with-declare-target.f90 diff --git a/openmp/libomptarget/test/offloading/fortran/target-map-allocatable-array-section-1d-bounds.f90 b/offload/test/offloading/fortran/target-map-allocatable-array-section-1d-bounds.f90 similarity index 100% rename from openmp/libomptarget/test/offloading/fortran/target-map-allocatable-array-section-1d-bounds.f90 rename to offload/test/offloading/fortran/target-map-allocatable-array-section-1d-bounds.f90 diff --git a/openmp/libomptarget/test/offloading/fortran/target-map-allocatable-array-section-3d-bounds.f90 b/offload/test/offloading/fortran/target-map-allocatable-array-section-3d-bounds.f90 similarity index 100% rename from openmp/libomptarget/test/offloading/fortran/target-map-allocatable-array-section-3d-bounds.f90 rename to offload/test/offloading/fortran/target-map-allocatable-array-section-3d-bounds.f90 diff --git a/openmp/libomptarget/test/offloading/fortran/target-map-allocatable-map-scopes.f90 b/offload/test/offloading/fortran/target-map-allocatable-map-scopes.f90 similarity index 100% rename from openmp/libomptarget/test/offloading/fortran/target-map-allocatable-map-scopes.f90 rename to offload/test/offloading/fortran/target-map-allocatable-map-scopes.f90 diff --git a/openmp/libomptarget/test/offloading/fortran/target-map-enter-exit-allocatables.f90 b/offload/test/offloading/fortran/target-map-enter-exit-allocatables.f90 similarity index 100% rename from openmp/libomptarget/test/offloading/fortran/target-map-enter-exit-allocatables.f90 rename to offload/test/offloading/fortran/target-map-enter-exit-allocatables.f90 diff --git a/openmp/libomptarget/test/offloading/fortran/target-map-enter-exit-array-2.f90 b/offload/test/offloading/fortran/target-map-enter-exit-array-2.f90 similarity index 100% rename from openmp/libomptarget/test/offloading/fortran/target-map-enter-exit-array-2.f90 rename to offload/test/offloading/fortran/target-map-enter-exit-array-2.f90 diff --git a/openmp/libomptarget/test/offloading/fortran/target-map-enter-exit-array-bounds.f90 b/offload/test/offloading/fortran/target-map-enter-exit-array-bounds.f90 similarity index 100% rename from openmp/libomptarget/test/offloading/fortran/target-map-enter-exit-array-bounds.f90 rename to offload/test/offloading/fortran/target-map-enter-exit-array-bounds.f90 diff --git a/openmp/libomptarget/test/offloading/fortran/target-map-enter-exit-array.f90 b/offload/test/offloading/fortran/target-map-enter-exit-array.f90 similarity index 100% rename from openmp/libomptarget/test/offloading/fortran/target-map-enter-exit-array.f90 rename to offload/test/offloading/fortran/target-map-enter-exit-array.f90 diff --git a/openmp/libomptarget/test/offloading/fortran/target-map-enter-exit-scalar.f90 b/offload/test/offloading/fortran/target-map-enter-exit-scalar.f90 similarity index 100% rename from openmp/libomptarget/test/offloading/fortran/target-map-enter-exit-scalar.f90 rename to offload/test/offloading/fortran/target-map-enter-exit-scalar.f90 diff --git a/openmp/libomptarget/test/offloading/fortran/target-map-pointer-scopes-enter-exit.f90 b/offload/test/offloading/fortran/target-map-pointer-scopes-enter-exit.f90 similarity index 100% rename from openmp/libomptarget/test/offloading/fortran/target-map-pointer-scopes-enter-exit.f90 rename to offload/test/offloading/fortran/target-map-pointer-scopes-enter-exit.f90 diff --git a/openmp/libomptarget/test/offloading/fortran/target-map-pointer-target-array-section-3d-bounds.f90 b/offload/test/offloading/fortran/target-map-pointer-target-array-section-3d-bounds.f90 similarity index 100% rename from openmp/libomptarget/test/offloading/fortran/target-map-pointer-target-array-section-3d-bounds.f90 rename to offload/test/offloading/fortran/target-map-pointer-target-array-section-3d-bounds.f90 diff --git a/openmp/libomptarget/test/offloading/fortran/target-map-pointer-target-scopes.f90 b/offload/test/offloading/fortran/target-map-pointer-target-scopes.f90 similarity index 100% rename from openmp/libomptarget/test/offloading/fortran/target-map-pointer-target-scopes.f90 rename to offload/test/offloading/fortran/target-map-pointer-target-scopes.f90 diff --git a/openmp/libomptarget/test/offloading/fortran/target-nested-target-data.f90 b/offload/test/offloading/fortran/target-nested-target-data.f90 similarity index 100% rename from openmp/libomptarget/test/offloading/fortran/target-nested-target-data.f90 rename to offload/test/offloading/fortran/target-nested-target-data.f90 diff --git a/openmp/libomptarget/test/offloading/fortran/target-parallel-do-collapse.f90 b/offload/test/offloading/fortran/target-parallel-do-collapse.f90 similarity index 100% rename from openmp/libomptarget/test/offloading/fortran/target-parallel-do-collapse.f90 rename to offload/test/offloading/fortran/target-parallel-do-collapse.f90 diff --git a/openmp/libomptarget/test/offloading/fortran/target-region-implicit-array.f90 b/offload/test/offloading/fortran/target-region-implicit-array.f90 similarity index 100% rename from openmp/libomptarget/test/offloading/fortran/target-region-implicit-array.f90 rename to offload/test/offloading/fortran/target-region-implicit-array.f90 diff --git a/openmp/libomptarget/test/offloading/fortran/target_map_common_block.f90 b/offload/test/offloading/fortran/target_map_common_block.f90 similarity index 100% rename from openmp/libomptarget/test/offloading/fortran/target_map_common_block.f90 rename to offload/test/offloading/fortran/target_map_common_block.f90 diff --git a/openmp/libomptarget/test/offloading/fortran/target_map_common_block1.f90 b/offload/test/offloading/fortran/target_map_common_block1.f90 similarity index 100% rename from openmp/libomptarget/test/offloading/fortran/target_map_common_block1.f90 rename to offload/test/offloading/fortran/target_map_common_block1.f90 diff --git a/openmp/libomptarget/test/offloading/fortran/target_map_common_block2.f90 b/offload/test/offloading/fortran/target_map_common_block2.f90 similarity index 100% rename from openmp/libomptarget/test/offloading/fortran/target_map_common_block2.f90 rename to offload/test/offloading/fortran/target_map_common_block2.f90 diff --git a/openmp/libomptarget/test/offloading/fortran/target_update.f90 b/offload/test/offloading/fortran/target_update.f90 similarity index 100% rename from openmp/libomptarget/test/offloading/fortran/target_update.f90 rename to offload/test/offloading/fortran/target_update.f90 diff --git a/openmp/libomptarget/test/offloading/generic_multiple_parallel_regions.c b/offload/test/offloading/generic_multiple_parallel_regions.c similarity index 100% rename from openmp/libomptarget/test/offloading/generic_multiple_parallel_regions.c rename to offload/test/offloading/generic_multiple_parallel_regions.c diff --git a/openmp/libomptarget/test/offloading/global_constructor.cpp b/offload/test/offloading/global_constructor.cpp similarity index 100% rename from openmp/libomptarget/test/offloading/global_constructor.cpp rename to offload/test/offloading/global_constructor.cpp diff --git a/openmp/libomptarget/test/offloading/host_as_target.c b/offload/test/offloading/host_as_target.c similarity index 100% rename from openmp/libomptarget/test/offloading/host_as_target.c rename to offload/test/offloading/host_as_target.c diff --git a/openmp/libomptarget/test/offloading/indirect_fp_mapping.c b/offload/test/offloading/indirect_fp_mapping.c similarity index 100% rename from openmp/libomptarget/test/offloading/indirect_fp_mapping.c rename to offload/test/offloading/indirect_fp_mapping.c diff --git a/openmp/libomptarget/test/offloading/info.c b/offload/test/offloading/info.c similarity index 100% rename from openmp/libomptarget/test/offloading/info.c rename to offload/test/offloading/info.c diff --git a/openmp/libomptarget/test/offloading/interop.c b/offload/test/offloading/interop.c similarity index 100% rename from openmp/libomptarget/test/offloading/interop.c rename to offload/test/offloading/interop.c diff --git a/openmp/libomptarget/test/offloading/lone_target_exit_data.c b/offload/test/offloading/lone_target_exit_data.c similarity index 100% rename from openmp/libomptarget/test/offloading/lone_target_exit_data.c rename to offload/test/offloading/lone_target_exit_data.c diff --git a/openmp/libomptarget/test/offloading/looptripcnt.c b/offload/test/offloading/looptripcnt.c similarity index 100% rename from openmp/libomptarget/test/offloading/looptripcnt.c rename to offload/test/offloading/looptripcnt.c diff --git a/openmp/libomptarget/test/offloading/malloc.c b/offload/test/offloading/malloc.c similarity index 100% rename from openmp/libomptarget/test/offloading/malloc.c rename to offload/test/offloading/malloc.c diff --git a/openmp/libomptarget/test/offloading/malloc_parallel.c b/offload/test/offloading/malloc_parallel.c similarity index 100% rename from openmp/libomptarget/test/offloading/malloc_parallel.c rename to offload/test/offloading/malloc_parallel.c diff --git a/openmp/libomptarget/test/offloading/mandatory_but_no_devices.c b/offload/test/offloading/mandatory_but_no_devices.c similarity index 100% rename from openmp/libomptarget/test/offloading/mandatory_but_no_devices.c rename to offload/test/offloading/mandatory_but_no_devices.c diff --git a/openmp/libomptarget/test/offloading/memory_manager.cpp b/offload/test/offloading/memory_manager.cpp similarity index 100% rename from openmp/libomptarget/test/offloading/memory_manager.cpp rename to offload/test/offloading/memory_manager.cpp diff --git a/openmp/libomptarget/test/offloading/multiple_reductions_simple.c b/offload/test/offloading/multiple_reductions_simple.c similarity index 100% rename from openmp/libomptarget/test/offloading/multiple_reductions_simple.c rename to offload/test/offloading/multiple_reductions_simple.c diff --git a/openmp/libomptarget/test/offloading/non_contiguous_update.cpp b/offload/test/offloading/non_contiguous_update.cpp similarity index 100% rename from openmp/libomptarget/test/offloading/non_contiguous_update.cpp rename to offload/test/offloading/non_contiguous_update.cpp diff --git a/openmp/libomptarget/test/offloading/offloading_success.c b/offload/test/offloading/offloading_success.c similarity index 100% rename from openmp/libomptarget/test/offloading/offloading_success.c rename to offload/test/offloading/offloading_success.c diff --git a/openmp/libomptarget/test/offloading/offloading_success.cpp b/offload/test/offloading/offloading_success.cpp similarity index 100% rename from openmp/libomptarget/test/offloading/offloading_success.cpp rename to offload/test/offloading/offloading_success.cpp diff --git a/openmp/libomptarget/test/offloading/ompx_bare.c b/offload/test/offloading/ompx_bare.c similarity index 100% rename from openmp/libomptarget/test/offloading/ompx_bare.c rename to offload/test/offloading/ompx_bare.c diff --git a/openmp/libomptarget/test/offloading/ompx_coords.c b/offload/test/offloading/ompx_coords.c similarity index 100% rename from openmp/libomptarget/test/offloading/ompx_coords.c rename to offload/test/offloading/ompx_coords.c diff --git a/openmp/libomptarget/test/offloading/ompx_saxpy_mixed.c b/offload/test/offloading/ompx_saxpy_mixed.c similarity index 100% rename from openmp/libomptarget/test/offloading/ompx_saxpy_mixed.c rename to offload/test/offloading/ompx_saxpy_mixed.c diff --git a/openmp/libomptarget/test/offloading/parallel_offloading_map.cpp b/offload/test/offloading/parallel_offloading_map.cpp similarity index 100% rename from openmp/libomptarget/test/offloading/parallel_offloading_map.cpp rename to offload/test/offloading/parallel_offloading_map.cpp diff --git a/openmp/libomptarget/test/offloading/parallel_target_teams_reduction.cpp b/offload/test/offloading/parallel_target_teams_reduction.cpp similarity index 100% rename from openmp/libomptarget/test/offloading/parallel_target_teams_reduction.cpp rename to offload/test/offloading/parallel_target_teams_reduction.cpp diff --git a/openmp/libomptarget/test/offloading/parallel_target_teams_reduction_max.cpp b/offload/test/offloading/parallel_target_teams_reduction_max.cpp similarity index 100% rename from openmp/libomptarget/test/offloading/parallel_target_teams_reduction_max.cpp rename to offload/test/offloading/parallel_target_teams_reduction_max.cpp diff --git a/openmp/libomptarget/test/offloading/parallel_target_teams_reduction_min.cpp b/offload/test/offloading/parallel_target_teams_reduction_min.cpp similarity index 100% rename from openmp/libomptarget/test/offloading/parallel_target_teams_reduction_min.cpp rename to offload/test/offloading/parallel_target_teams_reduction_min.cpp diff --git a/openmp/libomptarget/test/offloading/requires.c b/offload/test/offloading/requires.c similarity index 100% rename from openmp/libomptarget/test/offloading/requires.c rename to offload/test/offloading/requires.c diff --git a/openmp/libomptarget/test/offloading/runtime_init.c b/offload/test/offloading/runtime_init.c similarity index 100% rename from openmp/libomptarget/test/offloading/runtime_init.c rename to offload/test/offloading/runtime_init.c diff --git a/openmp/libomptarget/test/offloading/shared_lib_fp_mapping.c b/offload/test/offloading/shared_lib_fp_mapping.c similarity index 100% rename from openmp/libomptarget/test/offloading/shared_lib_fp_mapping.c rename to offload/test/offloading/shared_lib_fp_mapping.c diff --git a/openmp/libomptarget/test/offloading/small_trip_count.c b/offload/test/offloading/small_trip_count.c similarity index 100% rename from openmp/libomptarget/test/offloading/small_trip_count.c rename to offload/test/offloading/small_trip_count.c diff --git a/openmp/libomptarget/test/offloading/small_trip_count_thread_limit.cpp b/offload/test/offloading/small_trip_count_thread_limit.cpp similarity index 100% rename from openmp/libomptarget/test/offloading/small_trip_count_thread_limit.cpp rename to offload/test/offloading/small_trip_count_thread_limit.cpp diff --git a/openmp/libomptarget/test/offloading/spmdization.c b/offload/test/offloading/spmdization.c similarity index 100% rename from openmp/libomptarget/test/offloading/spmdization.c rename to offload/test/offloading/spmdization.c diff --git a/openmp/libomptarget/test/offloading/static_linking.c b/offload/test/offloading/static_linking.c similarity index 100% rename from openmp/libomptarget/test/offloading/static_linking.c rename to offload/test/offloading/static_linking.c diff --git a/openmp/libomptarget/test/offloading/std_complex_arithmetic.cpp b/offload/test/offloading/std_complex_arithmetic.cpp similarity index 100% rename from openmp/libomptarget/test/offloading/std_complex_arithmetic.cpp rename to offload/test/offloading/std_complex_arithmetic.cpp diff --git a/openmp/libomptarget/test/offloading/struct_mapping_with_pointers.cpp b/offload/test/offloading/struct_mapping_with_pointers.cpp similarity index 100% rename from openmp/libomptarget/test/offloading/struct_mapping_with_pointers.cpp rename to offload/test/offloading/struct_mapping_with_pointers.cpp diff --git a/openmp/libomptarget/test/offloading/target-teams-atomic.c b/offload/test/offloading/target-teams-atomic.c similarity index 100% rename from openmp/libomptarget/test/offloading/target-teams-atomic.c rename to offload/test/offloading/target-teams-atomic.c diff --git a/openmp/libomptarget/test/offloading/target-tile.c b/offload/test/offloading/target-tile.c similarity index 100% rename from openmp/libomptarget/test/offloading/target-tile.c rename to offload/test/offloading/target-tile.c diff --git a/openmp/libomptarget/test/offloading/target_constexpr_mapping.cpp b/offload/test/offloading/target_constexpr_mapping.cpp similarity index 100% rename from openmp/libomptarget/test/offloading/target_constexpr_mapping.cpp rename to offload/test/offloading/target_constexpr_mapping.cpp diff --git a/openmp/libomptarget/test/offloading/target_critical_region.cpp b/offload/test/offloading/target_critical_region.cpp similarity index 100% rename from openmp/libomptarget/test/offloading/target_critical_region.cpp rename to offload/test/offloading/target_critical_region.cpp diff --git a/openmp/libomptarget/test/offloading/target_depend_nowait.cpp b/offload/test/offloading/target_depend_nowait.cpp similarity index 100% rename from openmp/libomptarget/test/offloading/target_depend_nowait.cpp rename to offload/test/offloading/target_depend_nowait.cpp diff --git a/openmp/libomptarget/test/offloading/target_map_for_member_data.cpp b/offload/test/offloading/target_map_for_member_data.cpp similarity index 100% rename from openmp/libomptarget/test/offloading/target_map_for_member_data.cpp rename to offload/test/offloading/target_map_for_member_data.cpp diff --git a/openmp/libomptarget/test/offloading/target_nowait_target.cpp b/offload/test/offloading/target_nowait_target.cpp similarity index 100% rename from openmp/libomptarget/test/offloading/target_nowait_target.cpp rename to offload/test/offloading/target_nowait_target.cpp diff --git a/openmp/libomptarget/test/offloading/task_in_reduction_target.c b/offload/test/offloading/task_in_reduction_target.c similarity index 100% rename from openmp/libomptarget/test/offloading/task_in_reduction_target.c rename to offload/test/offloading/task_in_reduction_target.c diff --git a/openmp/libomptarget/test/offloading/taskloop_offload_nowait.cpp b/offload/test/offloading/taskloop_offload_nowait.cpp similarity index 100% rename from openmp/libomptarget/test/offloading/taskloop_offload_nowait.cpp rename to offload/test/offloading/taskloop_offload_nowait.cpp diff --git a/openmp/libomptarget/test/offloading/test_libc.cpp b/offload/test/offloading/test_libc.cpp similarity index 100% rename from openmp/libomptarget/test/offloading/test_libc.cpp rename to offload/test/offloading/test_libc.cpp diff --git a/openmp/libomptarget/test/offloading/thread_limit.c b/offload/test/offloading/thread_limit.c similarity index 100% rename from openmp/libomptarget/test/offloading/thread_limit.c rename to offload/test/offloading/thread_limit.c diff --git a/openmp/libomptarget/test/offloading/thread_state_1.c b/offload/test/offloading/thread_state_1.c similarity index 100% rename from openmp/libomptarget/test/offloading/thread_state_1.c rename to offload/test/offloading/thread_state_1.c diff --git a/openmp/libomptarget/test/offloading/thread_state_2.c b/offload/test/offloading/thread_state_2.c similarity index 100% rename from openmp/libomptarget/test/offloading/thread_state_2.c rename to offload/test/offloading/thread_state_2.c diff --git a/openmp/libomptarget/test/offloading/weak.c b/offload/test/offloading/weak.c similarity index 100% rename from openmp/libomptarget/test/offloading/weak.c rename to offload/test/offloading/weak.c diff --git a/openmp/libomptarget/test/offloading/workshare_chunk.c b/offload/test/offloading/workshare_chunk.c similarity index 100% rename from openmp/libomptarget/test/offloading/workshare_chunk.c rename to offload/test/offloading/workshare_chunk.c diff --git a/openmp/libomptarget/test/offloading/wtime.c b/offload/test/offloading/wtime.c similarity index 100% rename from openmp/libomptarget/test/offloading/wtime.c rename to offload/test/offloading/wtime.c diff --git a/openmp/libomptarget/test/ompt/callbacks.h b/offload/test/ompt/callbacks.h similarity index 100% rename from openmp/libomptarget/test/ompt/callbacks.h rename to offload/test/ompt/callbacks.h diff --git a/openmp/libomptarget/test/ompt/register_both.h b/offload/test/ompt/register_both.h similarity index 100% rename from openmp/libomptarget/test/ompt/register_both.h rename to offload/test/ompt/register_both.h diff --git a/openmp/libomptarget/test/ompt/register_emi.h b/offload/test/ompt/register_emi.h similarity index 100% rename from openmp/libomptarget/test/ompt/register_emi.h rename to offload/test/ompt/register_emi.h diff --git a/openmp/libomptarget/test/ompt/register_emi_map.h b/offload/test/ompt/register_emi_map.h similarity index 100% rename from openmp/libomptarget/test/ompt/register_emi_map.h rename to offload/test/ompt/register_emi_map.h diff --git a/openmp/libomptarget/test/ompt/register_no_device_init.h b/offload/test/ompt/register_no_device_init.h similarity index 100% rename from openmp/libomptarget/test/ompt/register_no_device_init.h rename to offload/test/ompt/register_no_device_init.h diff --git a/openmp/libomptarget/test/ompt/register_non_emi.h b/offload/test/ompt/register_non_emi.h similarity index 100% rename from openmp/libomptarget/test/ompt/register_non_emi.h rename to offload/test/ompt/register_non_emi.h diff --git a/openmp/libomptarget/test/ompt/register_non_emi_map.h b/offload/test/ompt/register_non_emi_map.h similarity index 100% rename from openmp/libomptarget/test/ompt/register_non_emi_map.h rename to offload/test/ompt/register_non_emi_map.h diff --git a/openmp/libomptarget/test/ompt/register_wrong_return.h b/offload/test/ompt/register_wrong_return.h similarity index 100% rename from openmp/libomptarget/test/ompt/register_wrong_return.h rename to offload/test/ompt/register_wrong_return.h diff --git a/openmp/libomptarget/test/ompt/target_memcpy.c b/offload/test/ompt/target_memcpy.c similarity index 100% rename from openmp/libomptarget/test/ompt/target_memcpy.c rename to offload/test/ompt/target_memcpy.c diff --git a/openmp/libomptarget/test/ompt/target_memcpy_emi.c b/offload/test/ompt/target_memcpy_emi.c similarity index 100% rename from openmp/libomptarget/test/ompt/target_memcpy_emi.c rename to offload/test/ompt/target_memcpy_emi.c diff --git a/openmp/libomptarget/test/ompt/veccopy.c b/offload/test/ompt/veccopy.c similarity index 100% rename from openmp/libomptarget/test/ompt/veccopy.c rename to offload/test/ompt/veccopy.c diff --git a/openmp/libomptarget/test/ompt/veccopy_data.c b/offload/test/ompt/veccopy_data.c similarity index 100% rename from openmp/libomptarget/test/ompt/veccopy_data.c rename to offload/test/ompt/veccopy_data.c diff --git a/openmp/libomptarget/test/ompt/veccopy_disallow_both.c b/offload/test/ompt/veccopy_disallow_both.c similarity index 100% rename from openmp/libomptarget/test/ompt/veccopy_disallow_both.c rename to offload/test/ompt/veccopy_disallow_both.c diff --git a/openmp/libomptarget/test/ompt/veccopy_emi.c b/offload/test/ompt/veccopy_emi.c similarity index 100% rename from openmp/libomptarget/test/ompt/veccopy_emi.c rename to offload/test/ompt/veccopy_emi.c diff --git a/openmp/libomptarget/test/ompt/veccopy_emi_map.c b/offload/test/ompt/veccopy_emi_map.c similarity index 100% rename from openmp/libomptarget/test/ompt/veccopy_emi_map.c rename to offload/test/ompt/veccopy_emi_map.c diff --git a/openmp/libomptarget/test/ompt/veccopy_map.c b/offload/test/ompt/veccopy_map.c similarity index 100% rename from openmp/libomptarget/test/ompt/veccopy_map.c rename to offload/test/ompt/veccopy_map.c diff --git a/openmp/libomptarget/test/ompt/veccopy_no_device_init.c b/offload/test/ompt/veccopy_no_device_init.c similarity index 100% rename from openmp/libomptarget/test/ompt/veccopy_no_device_init.c rename to offload/test/ompt/veccopy_no_device_init.c diff --git a/openmp/libomptarget/test/ompt/veccopy_wrong_return.c b/offload/test/ompt/veccopy_wrong_return.c similarity index 100% rename from openmp/libomptarget/test/ompt/veccopy_wrong_return.c rename to offload/test/ompt/veccopy_wrong_return.c diff --git a/openmp/libomptarget/test/unified_shared_memory/api.c b/offload/test/unified_shared_memory/api.c similarity index 100% rename from openmp/libomptarget/test/unified_shared_memory/api.c rename to offload/test/unified_shared_memory/api.c diff --git a/openmp/libomptarget/test/unified_shared_memory/associate_ptr.c b/offload/test/unified_shared_memory/associate_ptr.c similarity index 100% rename from openmp/libomptarget/test/unified_shared_memory/associate_ptr.c rename to offload/test/unified_shared_memory/associate_ptr.c diff --git a/openmp/libomptarget/test/unified_shared_memory/close_enter_exit.c b/offload/test/unified_shared_memory/close_enter_exit.c similarity index 100% rename from openmp/libomptarget/test/unified_shared_memory/close_enter_exit.c rename to offload/test/unified_shared_memory/close_enter_exit.c diff --git a/openmp/libomptarget/test/unified_shared_memory/close_manual.c b/offload/test/unified_shared_memory/close_manual.c similarity index 100% rename from openmp/libomptarget/test/unified_shared_memory/close_manual.c rename to offload/test/unified_shared_memory/close_manual.c diff --git a/openmp/libomptarget/test/unified_shared_memory/close_member.c b/offload/test/unified_shared_memory/close_member.c similarity index 100% rename from openmp/libomptarget/test/unified_shared_memory/close_member.c rename to offload/test/unified_shared_memory/close_member.c diff --git a/openmp/libomptarget/test/unified_shared_memory/close_modifier.c b/offload/test/unified_shared_memory/close_modifier.c similarity index 100% rename from openmp/libomptarget/test/unified_shared_memory/close_modifier.c rename to offload/test/unified_shared_memory/close_modifier.c diff --git a/openmp/libomptarget/test/unified_shared_memory/shared_update.c b/offload/test/unified_shared_memory/shared_update.c similarity index 100% rename from openmp/libomptarget/test/unified_shared_memory/shared_update.c rename to offload/test/unified_shared_memory/shared_update.c diff --git a/openmp/libomptarget/tools/CMakeLists.txt b/offload/tools/CMakeLists.txt similarity index 100% rename from openmp/libomptarget/tools/CMakeLists.txt rename to offload/tools/CMakeLists.txt diff --git a/openmp/libomptarget/tools/deviceinfo/CMakeLists.txt b/offload/tools/deviceinfo/CMakeLists.txt similarity index 100% rename from openmp/libomptarget/tools/deviceinfo/CMakeLists.txt rename to offload/tools/deviceinfo/CMakeLists.txt diff --git a/openmp/libomptarget/tools/deviceinfo/llvm-omp-device-info.cpp b/offload/tools/deviceinfo/llvm-omp-device-info.cpp similarity index 100% rename from openmp/libomptarget/tools/deviceinfo/llvm-omp-device-info.cpp rename to offload/tools/deviceinfo/llvm-omp-device-info.cpp diff --git a/openmp/libomptarget/tools/kernelreplay/CMakeLists.txt b/offload/tools/kernelreplay/CMakeLists.txt similarity index 100% rename from openmp/libomptarget/tools/kernelreplay/CMakeLists.txt rename to offload/tools/kernelreplay/CMakeLists.txt diff --git a/openmp/libomptarget/tools/kernelreplay/llvm-omp-kernel-replay.cpp b/offload/tools/kernelreplay/llvm-omp-kernel-replay.cpp similarity index 100% rename from openmp/libomptarget/tools/kernelreplay/llvm-omp-kernel-replay.cpp rename to offload/tools/kernelreplay/llvm-omp-kernel-replay.cpp diff --git a/openmp/libomptarget/unittests/CMakeLists.txt b/offload/unittests/CMakeLists.txt similarity index 100% rename from openmp/libomptarget/unittests/CMakeLists.txt rename to offload/unittests/CMakeLists.txt diff --git a/openmp/libomptarget/unittests/Plugins/CMakeLists.txt b/offload/unittests/Plugins/CMakeLists.txt similarity index 100% rename from openmp/libomptarget/unittests/Plugins/CMakeLists.txt rename to offload/unittests/Plugins/CMakeLists.txt diff --git a/openmp/libomptarget/unittests/Plugins/NextgenPluginsTest.cpp b/offload/unittests/Plugins/NextgenPluginsTest.cpp similarity index 100% rename from openmp/libomptarget/unittests/Plugins/NextgenPluginsTest.cpp rename to offload/unittests/Plugins/NextgenPluginsTest.cpp diff --git a/openmp/libomptarget/utils/generate_microtask_cases.py b/offload/utils/generate_microtask_cases.py similarity index 100% rename from openmp/libomptarget/utils/generate_microtask_cases.py rename to offload/utils/generate_microtask_cases.py diff --git a/openmp/CMakeLists.txt b/openmp/CMakeLists.txt index 3c4ff76ad6d1..95f2425db3ee 100644 --- a/openmp/CMakeLists.txt +++ b/openmp/CMakeLists.txt @@ -113,7 +113,17 @@ option(OPENMP_ENABLE_LIBOMP_PROFILING "Enable time profiling for libomp." OFF) # Header install location if(${OPENMP_STANDALONE_BUILD}) - set(LIBOMP_HEADERS_INSTALL_PATH "${CMAKE_INSTALL_INCLUDEDIR}") + if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + execute_process( + OUTPUT_STRIP_TRAILING_WHITESPACE + COMMAND ${CMAKE_CXX_COMPILER} --print-resource-dir + RESULT_VARIABLE COMMAND_RETURN_CODE + OUTPUT_VARIABLE COMPILER_RESOURCE_DIR + ) + set(LIBOMP_HEADERS_INSTALL_PATH "${COMPILER_RESOURCE_DIR}/include") + else() + set(LIBOMP_HEADERS_INSTALL_PATH "${CMAKE_INSTALL_INCLUDEDIR}") + endif() else() include(GetClangResourceDir) get_clang_resource_dir(LIBOMP_HEADERS_INSTALL_PATH SUBDIR include) @@ -123,19 +133,6 @@ endif() # to enable time profiling support in the OpenMP runtime. add_subdirectory(runtime) -if (OPENMP_ENABLE_LIBOMPTARGET) - # Check that the library can actually be built. - if (APPLE OR WIN32) - message(FATAL_ERROR "libomptarget cannot be built on Windows and MacOS X!") - elseif (NOT "cxx_std_17" IN_LIST CMAKE_CXX_COMPILE_FEATURES) - message(FATAL_ERROR "Host compiler must support C++17 to build libomptarget!") - elseif (NOT CMAKE_SIZEOF_VOID_P EQUAL 8) - message(FATAL_ERROR "libomptarget on 32-bit systems are not supported!") - endif() - - add_subdirectory(libomptarget) -endif() - set(ENABLE_OMPT_TOOLS ON) # Currently tools are not tested well on Windows or MacOS X. if (APPLE OR WIN32) @@ -148,6 +145,10 @@ if (OPENMP_ENABLE_OMPT_TOOLS) add_subdirectory(tools) endif() +# Propagate OMPT support to offload +set(LIBOMP_HAVE_OMPT_SUPPORT ${LIBOMP_HAVE_OMPT_SUPPORT} PARENT_SCOPE) +set(LIBOMP_OMP_TOOLS_INCLUDE_DIR ${LIBOMP_OMP_TOOLS_INCLUDE_DIR} PARENT_SCOPE) + option(OPENMP_MSVC_NAME_SCHEME "Build dll with MSVC naming scheme." OFF) # Build libompd.so diff --git a/openmp/libomptarget/test/api/ompx_dump_mapping_tables.cpp b/openmp/libomptarget/test/api/ompx_dump_mapping_tables.cpp deleted file mode 100644 index c170c2d73873..000000000000 --- a/openmp/libomptarget/test/api/ompx_dump_mapping_tables.cpp +++ /dev/null @@ -1,35 +0,0 @@ -// RUN: %libomptarget-compilexx-run-and-check-generic - -#include -#include - -#define N 10 - -int main() { - int *a = new __int32_t[N]; // mapped and released from device 0 - int *b = new __int32_t[2 * N]; // mapped to device 0 - - // clang-format off - // CHECK: Mapping tables after target enter data: - // CHECK-NEXT: omptarget device 0 info: OpenMP Host-Device pointer mappings after block - // CHECK-NEXT: omptarget device 0 info: Host Ptr Target Ptr Size (B) DynRefCount HoldRefCount Declaration - // CHECK-NEXT: omptarget device 0 info: {{(0x[0-9a-f]{16})}} {{(0x[0-9a-f]{16})}} {{[48]}}0 - // CHECK-NEXT: omptarget device 0 info: {{(0x[0-9a-f]{16})}} {{(0x[0-9a-f]{16})}} {{[48]}}0 -#pragma omp target enter data device(0) map(to : a[ : N]) -#pragma omp target enter data device(0) map(to : b[ : 2*N]) - // clang-format on - printf("Mapping tables after target enter data:\n"); - ompx_dump_mapping_tables(); - - // clang-format off - // CHECK: Mapping tables after target exit data for a: - // CHECK-NEXT: omptarget device 0 info: OpenMP Host-Device pointer mappings after block - // CHECK-NEXT: omptarget device 0 info: Host Ptr Target Ptr Size (B) DynRefCount HoldRefCount Declaration - // CHECK-NEXT: omptarget device 0 info: {{(0x[0-9a-f]{16})}} {{(0x[0-9a-f]{16})}} 80 -#pragma omp target exit data device(0) map(release : a[ : N]) - // clang-format on - printf("\nMapping tables after target exit data for a:\n"); - ompx_dump_mapping_tables(); - - return 0; -} diff --git a/openmp/runtime/src/CMakeLists.txt b/openmp/runtime/src/CMakeLists.txt index 701c35150f30..a2468d04e60a 100644 --- a/openmp/runtime/src/CMakeLists.txt +++ b/openmp/runtime/src/CMakeLists.txt @@ -229,6 +229,7 @@ if(NOT LIBOMP_LIBRARY_DIR) else() set(LIBOMP_LIBRARY_DIR ${LIBOMP_LIBRARY_DIR} PARENT_SCOPE) endif() +set(LIBOMP_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}) set(LIBOMP_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR} PARENT_SCOPE) # Add symbolic links to libomp @@ -241,7 +242,12 @@ if(NOT WIN32) WORKING_DIRECTORY ${LIBOMP_LIBRARY_DIR} ) endif() -set(LIBOMP_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR} PARENT_SCOPE) + +# Definitions for testing, for reuse when testing libomptarget-nvptx. +set(LIBOMPTARGET_OPENMP_HEADER_FOLDER "${LIBOMP_INCLUDE_DIR}" CACHE STRING + "Path to folder containing omp.h") +set(LIBOMPTARGET_OPENMP_HOST_RTL_FOLDER "${LIBOMP_LIBRARY_DIR}" CACHE STRING + "Path to folder containing libomp.so, and libLLVMSupport.so with profiling enabled") # Create *.inc before compiling any sources # objects depend on : .inc files diff --git a/runtimes/CMakeLists.txt b/runtimes/CMakeLists.txt index 6f24fbcccec9..fcc59c8fa1c3 100644 --- a/runtimes/CMakeLists.txt +++ b/runtimes/CMakeLists.txt @@ -21,7 +21,7 @@ list(INSERT CMAKE_MODULE_PATH 0 # We order libraries to mirror roughly how they are layered, except that compiler-rt can depend # on libc++, so we put it after. -set(LLVM_DEFAULT_RUNTIMES "libc;libunwind;libcxxabi;pstl;libcxx;compiler-rt;openmp") +set(LLVM_DEFAULT_RUNTIMES "libc;libunwind;libcxxabi;pstl;libcxx;compiler-rt;openmp;offload") set(LLVM_SUPPORTED_RUNTIMES "${LLVM_DEFAULT_RUNTIMES};llvm-libgcc") set(LLVM_ENABLE_RUNTIMES "" CACHE STRING "Semicolon-separated list of runtimes to build, or \"all\" (${LLVM_DEFAULT_RUNTIMES}). Supported runtimes are ${LLVM_SUPPORTED_RUNTIMES}.") -- GitLab From 8128d4b1229203c2ab20d3136410c149ea3652cf Mon Sep 17 00:00:00 2001 From: Stephen Tozer Date: Mon, 22 Apr 2024 18:04:15 +0100 Subject: [PATCH 004/732] [RemoveDIs] Preserve debug info format in llvm-reduce (#89220) As the goal of LLVM reduce is to simplify the input file, it should not modify the debug info format - doing so by default would make it impossible to reduce an error that only occurs in the old format, for example (as briefly discussed at https://github.com/llvm/llvm-project/pull/86275). This patch uses the new "preserve debug info format" flag in llvm-reduce to prevent the input from being subtly transformed by llvm-reduce itself; this has no effect on any tools used for the interestingness check (i.e. if `opt` is invoked, it will still convert the reduced input to the new format by default), but simply ensures that the reduced file is strictly reduced rather than modified. --- .../tools/llvm-reduce/remove-dp-values.ll | 24 +++++++++++-------- llvm/tools/llvm-reduce/llvm-reduce.cpp | 15 ++---------- 2 files changed, 16 insertions(+), 23 deletions(-) diff --git a/llvm/test/tools/llvm-reduce/remove-dp-values.ll b/llvm/test/tools/llvm-reduce/remove-dp-values.ll index d137b279f4ea..ab9cff4ae768 100644 --- a/llvm/test/tools/llvm-reduce/remove-dp-values.ll +++ b/llvm/test/tools/llvm-reduce/remove-dp-values.ll @@ -1,17 +1,21 @@ -; RUN: llvm-reduce --abort-on-invalid-reduction --test FileCheck --test-arg --check-prefixes=CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t --try-experimental-debuginfo-iterators -; RUN: FileCheck --check-prefixes=CHECK-FINAL --input-file=%t %s --implicit-check-not=dbg.value +; RUN: llvm-reduce --abort-on-invalid-reduction --test FileCheck --test-arg --check-prefixes=CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t +; RUN: FileCheck --check-prefixes=CHECK-FINAL --input-file=%t %s --implicit-check-not=#dbg_value + +; RUN: opt < %s -S --write-experimental-debuginfo=false > %t.intrinsics.ll +; RUN: llvm-reduce --abort-on-invalid-reduction --test FileCheck --test-arg --check-prefixes=INTRINSIC-INTERESTINGNESS --test-arg %s --test-arg --input-file %t.intrinsics.ll -o %t +; RUN: FileCheck --check-prefixes=INTRINSIC-FINAL --input-file=%t %s --implicit-check-not=#dbg_value ; Test that we can, in RemoveDIs mode / DbgVariableRecords mode (where variable location ; information isn't an instruction), remove one variable location assignment ; but not another. -; CHECK-INTERESTINGNESS: call void @llvm.dbg.value(metadata i32 %added, - -; CHECK-FINAL: declare void @llvm.dbg.value(metadata, -; CHECK-FINAL: %added = add -; CHECK-FINAL-NEXT: call void @llvm.dbg.value(metadata i32 %added, +; CHECK-INTERESTINGNESS: #dbg_value(i32 %added, +; INTRINSIC-INTERESTINGNESS: llvm.dbg.value(metadata i32 %added, -declare void @llvm.dbg.value(metadata, metadata, metadata) +; CHECK-FINAL: %added = add +; CHECK-FINAL-NEXT: #dbg_value(i32 %added, +; INTRINSIC-FINAL: %added = add +; INTRINSIC-FINAL-NEXT: llvm.dbg.value(metadata i32 %added, define i32 @main() !dbg !7 { entry: @@ -22,10 +26,10 @@ entry: store i32 0, ptr %interesting, align 4 %0 = load i32, ptr %interesting, align 4 %added = add nsw i32 %0, 1 - tail call void @llvm.dbg.value(metadata i32 %added, metadata !13, metadata !DIExpression()), !dbg !14 + #dbg_value(i32 %added, !13, !DIExpression(), !14) store i32 %added, ptr %interesting, align 4 %alsoloaded = load i32, ptr %interesting, align 4 - tail call void @llvm.dbg.value(metadata i32 %alsoloaded, metadata !13, metadata !DIExpression()), !dbg !14 + #dbg_value(i32 %alsoloaded, !13, !DIExpression(), !14) store i32 %alsoloaded, ptr %uninteresting2, align 4 ret i32 0 } diff --git a/llvm/tools/llvm-reduce/llvm-reduce.cpp b/llvm/tools/llvm-reduce/llvm-reduce.cpp index f913771487af..288a384c2ed4 100644 --- a/llvm/tools/llvm-reduce/llvm-reduce.cpp +++ b/llvm/tools/llvm-reduce/llvm-reduce.cpp @@ -100,12 +100,7 @@ static cl::opt "of delta passes (default=5)"), cl::init(5), cl::cat(LLVMReduceOptions)); -static cl::opt TryUseNewDbgInfoFormat( - "try-experimental-debuginfo-iterators", - cl::desc("Enable debuginfo iterator positions, if they're built in"), - cl::init(false)); - -extern cl::opt UseNewDbgInfoFormat; +extern cl::opt PreserveInputDbgFormat; static codegen::RegisterCodeGenFlags CGF; @@ -146,17 +141,11 @@ static std::pair determineOutputType(bool IsMIR, int main(int Argc, char **Argv) { InitLLVM X(Argc, Argv); const StringRef ToolName(Argv[0]); + PreserveInputDbgFormat = cl::boolOrDefault::BOU_TRUE; cl::HideUnrelatedOptions({&LLVMReduceOptions, &getColorCategory()}); cl::ParseCommandLineOptions(Argc, Argv, "LLVM automatic testcase reducer.\n"); - // RemoveDIs debug-info transition: tests may request that we /try/ to use the - // new debug-info format. - if (TryUseNewDbgInfoFormat) { - // Turn the new debug-info format on. - UseNewDbgInfoFormat = true; - } - if (Argc == 1) { cl::PrintHelpMessage(); return 0; -- GitLab From 7c20576cc37ab6b078782caf7575dab4ef87b37c Mon Sep 17 00:00:00 2001 From: Iman Hosseini Date: Mon, 22 Apr 2024 18:16:59 +0100 Subject: [PATCH 005/732] [flang][cuda] fix parsing of cuda_kernel (#89613) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix parsing of cuda_kernel: it missed a mlir::succeeded check and it was not setting up the `types` and causing mismatch between values and types of the grid/block (CUFKernelValues). @clementval --------- Co-authored-by: Iman Hosseini Co-authored-by: Valentin Clement (バレンタイン クレメン) --- flang/lib/Optimizer/Dialect/FIROps.cpp | 8 +++++++- flang/test/Lower/CUDA/cuda-kernel-loop-directive.cuf | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/flang/lib/Optimizer/Dialect/FIROps.cpp b/flang/lib/Optimizer/Dialect/FIROps.cpp index cc08f29a98f0..24af94f9b90a 100644 --- a/flang/lib/Optimizer/Dialect/FIROps.cpp +++ b/flang/lib/Optimizer/Dialect/FIROps.cpp @@ -3907,7 +3907,7 @@ mlir::ParseResult parseCUFKernelValues( if (mlir::succeeded(parser.parseOptionalStar())) return mlir::success(); - if (parser.parseOptionalLParen()) { + if (mlir::succeeded(parser.parseOptionalLParen())) { if (mlir::failed(parser.parseCommaSeparatedList( mlir::AsmParser::Delimiter::None, [&]() { if (parser.parseOperand(values.emplace_back())) @@ -3915,11 +3915,17 @@ mlir::ParseResult parseCUFKernelValues( return mlir::success(); }))) return mlir::failure(); + auto builder = parser.getBuilder(); + for (size_t i = 0; i < values.size(); i++) { + types.emplace_back(builder.getI32Type()); + } if (parser.parseRParen()) return mlir::failure(); } else { if (parser.parseOperand(values.emplace_back())) return mlir::failure(); + auto builder = parser.getBuilder(); + types.emplace_back(builder.getI32Type()); return mlir::success(); } return mlir::success(); diff --git a/flang/test/Lower/CUDA/cuda-kernel-loop-directive.cuf b/flang/test/Lower/CUDA/cuda-kernel-loop-directive.cuf index 6179e609db38..9b728cd19eb5 100644 --- a/flang/test/Lower/CUDA/cuda-kernel-loop-directive.cuf +++ b/flang/test/Lower/CUDA/cuda-kernel-loop-directive.cuf @@ -1,4 +1,5 @@ ! RUN: bbc -emit-hlfir -fcuda %s -o - | FileCheck %s +! RUN: bbc -emit-hlfir -fcuda %s -o - | fir-opt | FileCheck %s ! Test lowering of CUDA kernel loop directive. -- GitLab From 73ed2153beb529973741344874c0084d24c2f268 Mon Sep 17 00:00:00 2001 From: ZijunZhaoCCK Date: Mon, 22 Apr 2024 10:17:12 -0700 Subject: [PATCH 006/732] Carving out -Wformat warning about scoped enums into a subwarning (#88595) Make it part of -Wformat-pedantic. Fixes #81647 --- clang/docs/ReleaseNotes.rst | 2 ++ clang/lib/Sema/SemaChecking.cpp | 11 ++++++++--- clang/test/FixIt/format-darwin-enum-class.cpp | 4 ++-- clang/test/FixIt/format.cpp | 6 ++++-- clang/test/SemaCXX/format-strings.cpp | 4 ++-- 5 files changed, 18 insertions(+), 9 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index aea99680c79a..b5b351f3d30a 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -251,6 +251,8 @@ Modified Compiler Flags f3 *c = (f3 *)x; } +- Carved out ``-Wformat`` warning about scoped enums into a subwarning and + make it controlled by ``-Wformat-pedantic``. Fixes #GH88595. Removed Compiler Flags ------------------------- diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 2ef95741b3d6..51757f4cf727 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -12779,10 +12779,15 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS, // In this case, the expression could be printed using a different // specifier, but we've decided that the specifier is probably correct // and we should cast instead. Just use the normal warning message. + + unsigned Diag = + IsScopedEnum + ? diag::warn_format_conversion_argument_type_mismatch_pedantic + : diag::warn_format_conversion_argument_type_mismatch; + EmitFormatDiagnostic( - S.PDiag(diag::warn_format_conversion_argument_type_mismatch) - << AT.getRepresentativeTypeName(S.Context) << ExprTy << IsEnum - << E->getSourceRange(), + S.PDiag(Diag) << AT.getRepresentativeTypeName(S.Context) << ExprTy + << IsEnum << E->getSourceRange(), E->getBeginLoc(), /*IsStringLocation*/ false, SpecRange, Hints); } } diff --git a/clang/test/FixIt/format-darwin-enum-class.cpp b/clang/test/FixIt/format-darwin-enum-class.cpp index 5aa1a80d8614..6d0bb80e982d 100644 --- a/clang/test/FixIt/format-darwin-enum-class.cpp +++ b/clang/test/FixIt/format-darwin-enum-class.cpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin -fsyntax-only -verify -Wformat %s -// RUN: %clang_cc1 -triple x86_64-apple-darwin -fsyntax-only -fdiagnostics-parseable-fixits -Wformat %s 2>&1 | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin -fsyntax-only -verify -Wformat-pedantic %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin -fsyntax-only -fdiagnostics-parseable-fixits -Wformat-pedantic %s 2>&1 | FileCheck %s extern "C" int printf(const char * restrict, ...); diff --git a/clang/test/FixIt/format.cpp b/clang/test/FixIt/format.cpp index 4e6573a4f9e5..d663c0fb35e1 100644 --- a/clang/test/FixIt/format.cpp +++ b/clang/test/FixIt/format.cpp @@ -1,5 +1,7 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -Wformat %s -// RUN: %clang_cc1 -fsyntax-only -fdiagnostics-parseable-fixits -Wformat %s 2>&1 | FileCheck %s +// RUN: %clang_cc1 -fsyntax-only -verify -Wformat-pedantic %s +// RUN: %clang_cc1 -fsyntax-only -fdiagnostics-parseable-fixits -Wformat-pedantic %s 2>&1 | FileCheck %s +// RUN: %clang_cc1 -fsyntax-only -fdiagnostics-parseable-fixits -Wformat %s -verify=okay +// okay-no-diagnostics extern "C" int printf(const char *, ...); #define LOG(...) printf(__VA_ARGS__) diff --git a/clang/test/SemaCXX/format-strings.cpp b/clang/test/SemaCXX/format-strings.cpp index f554e905d645..48cf23999a94 100644 --- a/clang/test/SemaCXX/format-strings.cpp +++ b/clang/test/SemaCXX/format-strings.cpp @@ -1,6 +1,6 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -Wformat-nonliteral -Wformat-non-iso -fblocks %s +// RUN: %clang_cc1 -fsyntax-only -verify -Wformat-nonliteral -Wformat-non-iso -Wformat-pedantic -fblocks %s // RUN: %clang_cc1 -fsyntax-only -verify -Wformat-nonliteral -Wformat-non-iso -fblocks -std=c++98 %s -// RUN: %clang_cc1 -fsyntax-only -verify -Wformat-nonliteral -Wformat-non-iso -fblocks -std=c++11 %s +// RUN: %clang_cc1 -fsyntax-only -verify -Wformat-nonliteral -Wformat-non-iso -Wformat-pedantic -fblocks -std=c++11 %s #include -- GitLab From 772863e3120fc770ae1ab458022284be04810097 Mon Sep 17 00:00:00 2001 From: Kai Nacke Date: Mon, 22 Apr 2024 13:18:02 -0400 Subject: [PATCH 007/732] [SystemZ][NFC] Use new getPointerSize function (#89623) Use the new getPointerSize() function throughout the frame lowering class. --- .../lib/Target/SystemZ/SystemZFrameLowering.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp b/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp index 2683470afc5e..fa20977ec018 100644 --- a/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp +++ b/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp @@ -181,7 +181,8 @@ bool SystemZELFFrameLowering::assignCalleeSavedSpillSlots( StartSPOffset = Offset; } Offset -= SystemZMC::ELFCallFrameSize; - int FrameIdx = MFFrame.CreateFixedSpillStackObject(8, Offset); + int FrameIdx = + MFFrame.CreateFixedSpillStackObject(getPointerSize(), Offset); CS.setFrameIdx(FrameIdx); } else CS.setFrameIdx(INT32_MAX); @@ -456,8 +457,10 @@ void SystemZELFFrameLowering::processFunctionBeforeFrameFinalized( // are outside the reach of an unsigned 12-bit displacement. // Create 2 for the case where both addresses in an MVC are // out of range. - RS->addScavengingFrameIndex(MFFrame.CreateStackObject(8, Align(8), false)); - RS->addScavengingFrameIndex(MFFrame.CreateStackObject(8, Align(8), false)); + RS->addScavengingFrameIndex( + MFFrame.CreateStackObject(getPointerSize(), Align(8), false)); + RS->addScavengingFrameIndex( + MFFrame.CreateStackObject(getPointerSize(), Align(8), false)); } // If R6 is used as an argument register it is still callee saved. If it in @@ -870,7 +873,7 @@ int SystemZELFFrameLowering::getOrCreateFramePointerSaveIndex( if (!FI) { MachineFrameInfo &MFFrame = MF.getFrameInfo(); int Offset = getBackchainOffset(MF) - SystemZMC::ELFCallFrameSize; - FI = MFFrame.CreateFixedObject(8, Offset, false); + FI = MFFrame.CreateFixedObject(getPointerSize(), Offset, false); ZFI->setFramePointerSaveIndex(FI); } return FI; @@ -906,7 +909,7 @@ int SystemZXPLINKFrameLowering::getOrCreateFramePointerSaveIndex( int FI = ZFI->getFramePointerSaveIndex(); if (!FI) { MachineFrameInfo &MFFrame = MF.getFrameInfo(); - FI = MFFrame.CreateFixedObject(8, 0, false); + FI = MFFrame.CreateFixedObject(getPointerSize(), 0, false); MFFrame.setStackID(FI, TargetStackID::NoAlloc); ZFI->setFramePointerSaveIndex(FI); } @@ -1032,7 +1035,7 @@ bool SystemZXPLINKFrameLowering::assignCalleeSavedSpillSlots( // Non-volatile GPRs are saved in the dedicated register save area at // the bottom of the stack and are not truly part of the "normal" stack // frame. Mark the frame index as NoAlloc to indicate it as such. - unsigned RegSize = 8; + unsigned RegSize = getPointerSize(); int FrameIdx = (FPSI && Offset == 0) ? FPSI @@ -1302,7 +1305,7 @@ void SystemZXPLINKFrameLowering::emitPrologue(MachineFunction &MF, for (unsigned I = FixedRegs; I < SystemZ::XPLINK64NumArgGPRs; I++) { uint64_t StartOffset = MFFrame.getOffsetAdjustment() + MFFrame.getStackSize() + Regs.getCallFrameSize() + - getOffsetOfLocalArea() + I * 8; + getOffsetOfLocalArea() + I * getPointerSize(); unsigned Reg = GPRs[I]; BuildMI(MBB, MBBI, DL, TII->get(SystemZ::STG)) .addReg(Reg) -- GitLab From 180cf4daec290e68aa4dd6dc14697add3e18bcec Mon Sep 17 00:00:00 2001 From: zibi2 <62662650+zibi2@users.noreply.github.com> Date: Mon, 22 Apr 2024 13:24:47 -0400 Subject: [PATCH 008/732] [clangd] Fix unittests in TargetDeclTest bucket (#89630) This PR fixes the build errors for one of the `clangd` unit tests bucket similar to the following: ``` .../clang-tools-extra/clangd/unittests/FindTargetTests.cpp:430:29: error: passing no argument for the '...' parameter of a variadic macro is a C++20 extension [-Werror,-Wc++20-extensions] 430 | EXPECT_DECLS("AutoTypeLoc"); | ^ .../clang-tools-extra/clangd/unittests/FindTargetTests.cpp:98:9: note: macro 'EXPECT_DECLS' defined here 98 | #define EXPECT_DECLS(NodeType, ...) \ | ^ ``` This happens when using a build compiler with #84520. The fix is to include commas to compensate for empty vararg macro arguments in a few instances. --- .../clangd/unittests/FindTargetTests.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp index 0af6036734ba..799a549ff081 100644 --- a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp +++ b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp @@ -427,7 +427,7 @@ TEST_F(TargetDeclTest, Types) { [[auto]] X = S{}; )cpp"; // FIXME: deduced type missing in AST. https://llvm.org/PR42914 - EXPECT_DECLS("AutoTypeLoc"); + EXPECT_DECLS("AutoTypeLoc", ); Code = R"cpp( template @@ -727,13 +727,13 @@ TEST_F(TargetDeclTest, BuiltinTemplates) { template using make_integer_sequence = [[__make_integer_seq]]; )cpp"; - EXPECT_DECLS("TemplateSpecializationTypeLoc"); + EXPECT_DECLS("TemplateSpecializationTypeLoc", ); Code = R"cpp( template using type_pack_element = [[__type_pack_element]]; )cpp"; - EXPECT_DECLS("TemplateSpecializationTypeLoc"); + EXPECT_DECLS("TemplateSpecializationTypeLoc", ); } TEST_F(TargetDeclTest, MemberOfTemplate) { @@ -1018,7 +1018,7 @@ TEST_F(TargetDeclTest, DependentTypes) { typedef typename waldo::type::[[next]] type; }; )cpp"; - EXPECT_DECLS("DependentNameTypeLoc"); + EXPECT_DECLS("DependentNameTypeLoc", ); // Similar to above but using mutually recursive templates. Code = R"cpp( @@ -1035,7 +1035,7 @@ TEST_F(TargetDeclTest, DependentTypes) { using type = typename even::type::[[next]]; }; )cpp"; - EXPECT_DECLS("DependentNameTypeLoc"); + EXPECT_DECLS("DependentNameTypeLoc", ); } TEST_F(TargetDeclTest, TypedefCascade) { @@ -1263,14 +1263,14 @@ TEST_F(TargetDeclTest, ObjC) { + ([[id]])sharedInstance; @end )cpp"; - EXPECT_DECLS("TypedefTypeLoc"); + EXPECT_DECLS("TypedefTypeLoc", ); Code = R"cpp( @interface Foo + ([[instancetype]])sharedInstance; @end )cpp"; - EXPECT_DECLS("TypedefTypeLoc"); + EXPECT_DECLS("TypedefTypeLoc", ); } class FindExplicitReferencesTest : public ::testing::Test { -- GitLab From 9aa663bb9ef3dbab8ccc324ef3df5138aa458fbd Mon Sep 17 00:00:00 2001 From: Nikolas Klauser Date: Mon, 22 Apr 2024 19:26:33 +0200 Subject: [PATCH 009/732] [Clang] Fix __is_trivially_equaltiy_comparable documentation (#88528) Currently `__is_trivially_equality_comparable` is documented to return true if comparing the value representation is equivalent to calling the comparison operator, which is not quite what the trait actually checks. The traits actually checks that comparing the object representation is equivalent, which means that there cannot be padding bytes in the type. --- clang/docs/LanguageExtensions.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst index 3bead159c8f9..84fc4dee02fa 100644 --- a/clang/docs/LanguageExtensions.rst +++ b/clang/docs/LanguageExtensions.rst @@ -1642,7 +1642,8 @@ The following type trait primitives are supported by Clang. Those traits marked were made trivially relocatable via the ``clang::trivial_abi`` attribute. * ``__is_trivially_equality_comparable`` (Clang): Returns true if comparing two objects of the provided type is known to be equivalent to comparing their - value representations. + object representations. Note that types containing padding bytes are never + trivially equality comparable. * ``__is_unbounded_array`` (C++, GNU, Microsoft, Embarcadero) * ``__is_union`` (C++, GNU, Microsoft, Embarcadero) * ``__is_unsigned`` (C++, Embarcadero): -- GitLab From a6c028299cbce9885dd3c3e989b2cb3273ba6e05 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Mon, 22 Apr 2024 10:32:47 -0700 Subject: [PATCH 010/732] [RISCV] Add extension information to RISCVFeatures.td. NFC (#89326) This adds a new RISCVExtension class that inherits from SubtargetFeature. This contains the major/minor version and whether the extension is experimental. The plan is to use this to generate the tables for RISCVISAInfo.cpp. The version numbers might not be accurate yet. If there are errors they will be fixed before they are used for anything. It will be easier to verify once the new tablegen backend is written to generate the RISCVISAInfo.cpp table. --- llvm/lib/Target/RISCV/RISCVFeatures.td | 810 +++++++++++++------------ 1 file changed, 425 insertions(+), 385 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td index 116e5a2ab734..b064191b838e 100644 --- a/llvm/lib/Target/RISCV/RISCVFeatures.td +++ b/llvm/lib/Target/RISCV/RISCVFeatures.td @@ -10,119 +10,157 @@ // RISC-V subtarget features and instruction predicates. //===----------------------------------------------------------------------===// +// Subclass of SubtargetFeature to be used when the feature is also a RISC-V +// extension. Extensions have a version and may be experimental. +// +// name - Name of the extension in lower case. +// major - Major version of extension. +// minor - Minor version of extension. +// desc - Description of extension. +// implies - Extensions or features implied by this extension. +// fieldname - name of field to create in RISCVSubtarget. By default replaces +// uses the record name by replacing Feature with Has. +// value - Value to assign to the field in RISCVSubtarget when this +// extension is enabled. Usually "true", but can be changed. +class RISCVExtension implies = [], + string fieldname = !subst("Feature", "Has", NAME), + string value = "true"> + : SubtargetFeature { + // MajorVersion - The major version for this extension. + int MajorVersion = major; + + // MinorVersion - The minor version for this extension. + int MinorVersion = minor; + + // Experimental - Does extension require -menable-experimental-extensions. + bit Experimental = false; +} + +// Version of RISCVExtension to be used for Experimental extensions. This +// sets the Experimental flag and prepends experimental- to the -mattr name. +class RISCVExperimentalExtension implies = [], + string fieldname = !subst("Feature", "Has", NAME), + string value = "true"> + : RISCVExtension<"experimental-"#name, major, minor, desc, implies, + fieldname, value> { + let Experimental = true; +} + // Integer Extensions def FeatureStdExtI - : SubtargetFeature<"i", "HasStdExtI", "true", - "'I' (Base Integer Instruction Set)">; + : RISCVExtension<"i", 2, 1, + "'I' (Base Integer Instruction Set)">; def FeatureStdExtE - : SubtargetFeature<"e", "HasStdExtE", "true", - "Implements RV{32,64}E (provides 16 rather than 32 GPRs)">; + : RISCVExtension<"e", 2, 0, + "Implements RV{32,64}E (provides 16 rather than 32 GPRs)">; def FeatureStdExtZic64b - : SubtargetFeature<"zic64b", "HasStdExtZic64b", "true", - "'Zic64b' (Cache Block Size Is 64 Bytes)">; + : RISCVExtension<"zic64b", 1, 0, + "'Zic64b' (Cache Block Size Is 64 Bytes)">; def FeatureStdExtZicbom - : SubtargetFeature<"zicbom", "HasStdExtZicbom", "true", - "'Zicbom' (Cache-Block Management Instructions)">; + : RISCVExtension<"zicbom", 1, 0, + "'Zicbom' (Cache-Block Management Instructions)">; def HasStdExtZicbom : Predicate<"Subtarget->hasStdExtZicbom()">, AssemblerPredicate<(all_of FeatureStdExtZicbom), "'Zicbom' (Cache-Block Management Instructions)">; def FeatureStdExtZicbop - : SubtargetFeature<"zicbop", "HasStdExtZicbop", "true", - "'Zicbop' (Cache-Block Prefetch Instructions)">; + : RISCVExtension<"zicbop", 1, 0, + "'Zicbop' (Cache-Block Prefetch Instructions)">; def HasStdExtZicbop : Predicate<"Subtarget->hasStdExtZicbop()">, AssemblerPredicate<(all_of FeatureStdExtZicbop), "'Zicbop' (Cache-Block Prefetch Instructions)">; def FeatureStdExtZicboz - : SubtargetFeature<"zicboz", "HasStdExtZicboz", "true", - "'Zicboz' (Cache-Block Zero Instructions)">; + : RISCVExtension<"zicboz", 1, 0, + "'Zicboz' (Cache-Block Zero Instructions)">; def HasStdExtZicboz : Predicate<"Subtarget->hasStdExtZicboz()">, AssemblerPredicate<(all_of FeatureStdExtZicboz), "'Zicboz' (Cache-Block Zero Instructions)">; def FeatureStdExtZiccamoa - : SubtargetFeature<"ziccamoa", "HasStdExtZiccamoa", "true", - "'Ziccamoa' (Main Memory Supports All Atomics in A)">; + : RISCVExtension<"ziccamoa", 1, 0, + "'Ziccamoa' (Main Memory Supports All Atomics in A)">; def FeatureStdExtZiccif - : SubtargetFeature<"ziccif", "HasStdExtZiccif", "true", - "'Ziccif' (Main Memory Supports Instruction Fetch with Atomicity Requirement)">; + : RISCVExtension<"ziccif", 1, 0, + "'Ziccif' (Main Memory Supports Instruction Fetch with Atomicity Requirement)">; def FeatureStdExtZicclsm - : SubtargetFeature<"zicclsm", "HasStdExtZicclsm", "true", - "'Zicclsm' (Main Memory Supports Misaligned Loads/Stores)">; + : RISCVExtension<"zicclsm", 1, 0, + "'Zicclsm' (Main Memory Supports Misaligned Loads/Stores)">; def FeatureStdExtZiccrse - : SubtargetFeature<"ziccrse", "HasStdExtZiccrse", "true", - "'Ziccrse' (Main Memory Supports Forward Progress on LR/SC Sequences)">; + : RISCVExtension<"ziccrse", 1, 0, + "'Ziccrse' (Main Memory Supports Forward Progress on LR/SC Sequences)">; def FeatureStdExtZicsr - : SubtargetFeature<"zicsr", "HasStdExtZicsr", "true", - "'zicsr' (CSRs)">; + : RISCVExtension<"zicsr", 2, 0, + "'zicsr' (CSRs)">; def HasStdExtZicsr : Predicate<"Subtarget->hasStdExtZicsr()">, AssemblerPredicate<(all_of FeatureStdExtZicsr), "'Zicsr' (CSRs)">; def FeatureStdExtZicntr - : SubtargetFeature<"zicntr", "HasStdExtZicntr", "true", - "'Zicntr' (Base Counters and Timers)", + : RISCVExtension<"zicntr", 2, 0, + "'Zicntr' (Base Counters and Timers)", [FeatureStdExtZicsr]>; def FeatureStdExtZicond - : SubtargetFeature<"zicond", "HasStdExtZicond", "true", - "'Zicond' (Integer Conditional Operations)">; + : RISCVExtension<"zicond", 1, 0, + "'Zicond' (Integer Conditional Operations)">; def HasStdExtZicond : Predicate<"Subtarget->hasStdExtZicond()">, AssemblerPredicate<(all_of FeatureStdExtZicond), "'Zicond' (Integer Conditional Operations)">; def FeatureStdExtZifencei - : SubtargetFeature<"zifencei", "HasStdExtZifencei", "true", - "'Zifencei' (fence.i)">; + : RISCVExtension<"zifencei", 2, 0, + "'Zifencei' (fence.i)">; def HasStdExtZifencei : Predicate<"Subtarget->hasStdExtZifencei()">, AssemblerPredicate<(all_of FeatureStdExtZifencei), "'Zifencei' (fence.i)">; def FeatureStdExtZihintpause - : SubtargetFeature<"zihintpause", "HasStdExtZihintpause", "true", - "'Zihintpause' (Pause Hint)">; + : RISCVExtension<"zihintpause", 2, 0, + "'Zihintpause' (Pause Hint)">; def HasStdExtZihintpause : Predicate<"Subtarget->hasStdExtZihintpause()">, AssemblerPredicate<(all_of FeatureStdExtZihintpause), "'Zihintpause' (Pause Hint)">; def FeatureStdExtZihintntl - : SubtargetFeature<"zihintntl", "HasStdExtZihintntl", "true", - "'Zihintntl' (Non-Temporal Locality Hints)">; + : RISCVExtension<"zihintntl", 1, 0, + "'Zihintntl' (Non-Temporal Locality Hints)">; def HasStdExtZihintntl : Predicate<"Subtarget->hasStdExtZihintntl()">, AssemblerPredicate<(all_of FeatureStdExtZihintntl), "'Zihintntl' (Non-Temporal Locality Hints)">; def FeatureStdExtZihpm - : SubtargetFeature<"zihpm", "HasStdExtZihpm", "true", - "'Zihpm' (Hardware Performance Counters)", - [FeatureStdExtZicsr]>; + : RISCVExtension<"zihpm", 2, 0, + "'Zihpm' (Hardware Performance Counters)", + [FeatureStdExtZicsr]>; -def FeatureStdExtZimop : SubtargetFeature<"zimop", "HasStdExtZimop", "true", - "'Zimop' (May-Be-Operations)">; +def FeatureStdExtZimop : RISCVExtension<"zimop", 1, 0, + "'Zimop' (May-Be-Operations)">; def HasStdExtZimop : Predicate<"Subtarget->hasStdExtZimop()">, AssemblerPredicate<(all_of FeatureStdExtZimop), "'Zimop' (May-Be-Operations)">; def FeatureStdExtZicfilp - : SubtargetFeature<"experimental-zicfilp", "HasStdExtZicfilp", "true", - "'Zicfilp' (Landing pad)">; + : RISCVExperimentalExtension<"zicfilp", 0, 4, + "'Zicfilp' (Landing pad)">; def HasStdExtZicfilp : Predicate<"Subtarget->hasStdExtZicfilp()">, AssemblerPredicate<(all_of FeatureStdExtZicfilp), "'Zicfilp' (Landing pad)">; def FeatureStdExtZicfiss - : SubtargetFeature<"experimental-zicfiss", "HasStdExtZicfiss", "true", - "'Zicfiss' (Shadow stack)", - [FeatureStdExtZicsr, FeatureStdExtZimop]>; + : RISCVExperimentalExtension<"zicfiss", 0, 4, + "'Zicfiss' (Shadow stack)", + [FeatureStdExtZicsr, FeatureStdExtZimop]>; def HasStdExtZicfiss : Predicate<"Subtarget->hasStdExtZicfiss()">, AssemblerPredicate<(all_of FeatureStdExtZicfiss), "'Zicfiss' (Shadow stack)">; @@ -131,15 +169,15 @@ def NoHasStdExtZicfiss : Predicate<"!Subtarget->hasStdExtZicfiss()">; // Multiply Extensions def FeatureStdExtM - : SubtargetFeature<"m", "HasStdExtM", "true", - "'M' (Integer Multiplication and Division)">; + : RISCVExtension<"m", 2, 0, + "'M' (Integer Multiplication and Division)">; def HasStdExtM : Predicate<"Subtarget->hasStdExtM()">, AssemblerPredicate<(all_of FeatureStdExtM), "'M' (Integer Multiplication and Division)">; def FeatureStdExtZmmul - : SubtargetFeature<"zmmul", "HasStdExtZmmul", "true", - "'Zmmul' (Integer Multiplication)">; + : RISCVExtension<"zmmul", 1, 0, + "'Zmmul' (Integer Multiplication)">; def HasStdExtMOrZmmul : Predicate<"Subtarget->hasStdExtM() || Subtarget->hasStdExtZmmul()">, @@ -150,29 +188,29 @@ def HasStdExtMOrZmmul // Atomic Extensions def FeatureStdExtA - : SubtargetFeature<"a", "HasStdExtA", "true", - "'A' (Atomic Instructions)">; + : RISCVExtension<"a", 2, 1, + "'A' (Atomic Instructions)">; def HasStdExtA : Predicate<"Subtarget->hasStdExtA()">, AssemblerPredicate<(all_of FeatureStdExtA), "'A' (Atomic Instructions)">; def FeatureStdExtZtso - : SubtargetFeature<"experimental-ztso", "HasStdExtZtso", "true", - "'Ztso' (Memory Model - Total Store Order)">; + : RISCVExperimentalExtension<"ztso", 0, 1, + "'Ztso' (Memory Model - Total Store Order)">; def HasStdExtZtso : Predicate<"Subtarget->hasStdExtZtso()">, AssemblerPredicate<(all_of FeatureStdExtZtso), "'Ztso' (Memory Model - Total Store Order)">; def NotHasStdExtZtso : Predicate<"!Subtarget->hasStdExtZtso()">; -def FeatureStdExtZa64rs : SubtargetFeature<"za64rs", "HasStdExtZa64rs", "true", - "'Za64rs' (Reservation Set Size of at Most 64 Bytes)">; +def FeatureStdExtZa64rs : RISCVExtension<"za64rs", 1, 0, + "'Za64rs' (Reservation Set Size of at Most 64 Bytes)">; -def FeatureStdExtZa128rs : SubtargetFeature<"za128rs", "HasStdExtZa128rs", "true", - "'Za128rs' (Reservation Set Size of at Most 128 Bytes)">; +def FeatureStdExtZa128rs : RISCVExtension<"za128rs", 1, 0, + "'Za128rs' (Reservation Set Size of at Most 128 Bytes)">; def FeatureStdExtZaamo - : SubtargetFeature<"experimental-zaamo", "HasStdExtZaamo", "true", - "'Zaamo' (Atomic Memory Operations)">; + : RISCVExperimentalExtension<"zaamo", 0, 2, + "'Zaamo' (Atomic Memory Operations)">; def HasStdExtAOrZaamo : Predicate<"Subtarget->hasStdExtA() || Subtarget->hasStdExtZaamo()">, AssemblerPredicate<(any_of FeatureStdExtA, FeatureStdExtZaamo), @@ -180,30 +218,30 @@ def HasStdExtAOrZaamo "'Zaamo' (Atomic Memory Operations)">; def FeatureStdExtZabha - : SubtargetFeature<"experimental-zabha", "HasStdExtZabha", "true", - "'Zabha' (Byte and Halfword Atomic Memory Operations)">; + : RISCVExperimentalExtension<"zabha", 1, 0, + "'Zabha' (Byte and Halfword Atomic Memory Operations)">; def HasStdExtZabha : Predicate<"Subtarget->hasStdExtZabha()">, AssemblerPredicate<(all_of FeatureStdExtZabha), "'Zabha' (Byte and Halfword Atomic Memory Operations)">; def FeatureStdExtZacas - : SubtargetFeature<"zacas", "HasStdExtZacas", "true", - "'Zacas' (Atomic Compare-And-Swap Instructions)">; + : RISCVExtension<"zacas", 1, 0, + "'Zacas' (Atomic Compare-And-Swap Instructions)">; def HasStdExtZacas : Predicate<"Subtarget->hasStdExtZacas()">, AssemblerPredicate<(all_of FeatureStdExtZacas), "'Zacas' (Atomic Compare-And-Swap Instructions)">; def NoStdExtZacas : Predicate<"!Subtarget->hasStdExtZacas()">; def FeatureStdExtZalasr - : SubtargetFeature<"experimental-zalasr", "HasStdExtZalasr", "true", - "'Zalasr' (Load-Acquire and Store-Release Instructions)">; + : RISCVExperimentalExtension<"zalasr", 0, 1, + "'Zalasr' (Load-Acquire and Store-Release Instructions)">; def HasStdExtZalasr : Predicate<"Subtarget->hasStdExtZalasr()">, AssemblerPredicate<(all_of FeatureStdExtZalasr), "'Zalasr' (Load-Acquire and Store-Release Instructions)">; def FeatureStdExtZalrsc - : SubtargetFeature<"experimental-zalrsc", "HasStdExtZalrsc", "true", - "'Zalrsc' (Load-Reserved/Store-Conditional)">; + : RISCVExperimentalExtension<"zalrsc", 0, 2, + "'Zalrsc' (Load-Reserved/Store-Conditional)">; def HasStdExtAOrZalrsc : Predicate<"Subtarget->hasStdExtA() || Subtarget->hasStdExtZalrsc()">, AssemblerPredicate<(any_of FeatureStdExtA, FeatureStdExtZalrsc), @@ -211,11 +249,11 @@ def HasStdExtAOrZalrsc "'Zalrsc' (Load-Reserved/Store-Conditional)">; def FeatureStdExtZama16b - : SubtargetFeature<"zama16b", "HasStdExtZama16b", "true", - "'Zama16b' (Atomic 16-byte misaligned loads, stores and AMOs)">; + : RISCVExtension<"zama16b", 1, 0, + "'Zama16b' (Atomic 16-byte misaligned loads, stores and AMOs)">; -def FeatureStdExtZawrs : SubtargetFeature<"zawrs", "HasStdExtZawrs", "true", - "'Zawrs' (Wait on Reservation Set)">; +def FeatureStdExtZawrs : RISCVExtension<"zawrs", 1, 0, + "'Zawrs' (Wait on Reservation Set)">; def HasStdExtZawrs : Predicate<"Subtarget->hasStdExtZawrs()">, AssemblerPredicate<(all_of FeatureStdExtZawrs), "'Zawrs' (Wait on Reservation Set)">; @@ -223,43 +261,43 @@ def HasStdExtZawrs : Predicate<"Subtarget->hasStdExtZawrs()">, // Floating Point Extensions def FeatureStdExtF - : SubtargetFeature<"f", "HasStdExtF", "true", - "'F' (Single-Precision Floating-Point)", - [FeatureStdExtZicsr]>; + : RISCVExtension<"f", 2, 2, + "'F' (Single-Precision Floating-Point)", + [FeatureStdExtZicsr]>; def HasStdExtF : Predicate<"Subtarget->hasStdExtF()">, AssemblerPredicate<(all_of FeatureStdExtF), "'F' (Single-Precision Floating-Point)">; def FeatureStdExtD - : SubtargetFeature<"d", "HasStdExtD", "true", - "'D' (Double-Precision Floating-Point)", - [FeatureStdExtF]>; + : RISCVExtension<"d", 2, 2, + "'D' (Double-Precision Floating-Point)", + [FeatureStdExtF]>; def HasStdExtD : Predicate<"Subtarget->hasStdExtD()">, AssemblerPredicate<(all_of FeatureStdExtD), "'D' (Double-Precision Floating-Point)">; def FeatureStdExtZfhmin - : SubtargetFeature<"zfhmin", "HasStdExtZfhmin", "true", - "'Zfhmin' (Half-Precision Floating-Point Minimal)", - [FeatureStdExtF]>; + : RISCVExtension<"zfhmin", 1, 0, + "'Zfhmin' (Half-Precision Floating-Point Minimal)", + [FeatureStdExtF]>; def HasStdExtZfhmin : Predicate<"Subtarget->hasStdExtZfhmin()">, AssemblerPredicate<(all_of FeatureStdExtZfhmin), "'Zfh' (Half-Precision Floating-Point) or " "'Zfhmin' (Half-Precision Floating-Point Minimal)">; def FeatureStdExtZfh - : SubtargetFeature<"zfh", "HasStdExtZfh", "true", - "'Zfh' (Half-Precision Floating-Point)", - [FeatureStdExtZfhmin]>; + : RISCVExtension<"zfh", 1, 0, + "'Zfh' (Half-Precision Floating-Point)", + [FeatureStdExtZfhmin]>; def HasStdExtZfh : Predicate<"Subtarget->hasStdExtZfh()">, AssemblerPredicate<(all_of FeatureStdExtZfh), "'Zfh' (Half-Precision Floating-Point)">; def NoStdExtZfh : Predicate<"!Subtarget->hasStdExtZfh()">; def FeatureStdExtZfbfmin - : SubtargetFeature<"experimental-zfbfmin", "HasStdExtZfbfmin", "true", - "'Zfbfmin' (Scalar BF16 Converts)", - [FeatureStdExtF]>; + : RISCVExperimentalExtension<"zfbfmin", 1, 0, + "'Zfbfmin' (Scalar BF16 Converts)", + [FeatureStdExtF]>; def HasStdExtZfbfmin : Predicate<"Subtarget->hasStdExtZfbfmin()">, AssemblerPredicate<(all_of FeatureStdExtZfbfmin), "'Zfbfmin' (Scalar BF16 Converts)">; @@ -273,42 +311,42 @@ def HasHalfFPLoadStoreMove "'Zfbfmin' (Scalar BF16 Converts)">; def FeatureStdExtZfa - : SubtargetFeature<"zfa", "HasStdExtZfa", "true", - "'Zfa' (Additional Floating-Point)", - [FeatureStdExtF]>; + : RISCVExtension<"zfa", 1, 0, + "'Zfa' (Additional Floating-Point)", + [FeatureStdExtF]>; def HasStdExtZfa : Predicate<"Subtarget->hasStdExtZfa()">, AssemblerPredicate<(all_of FeatureStdExtZfa), "'Zfa' (Additional Floating-Point)">; def FeatureStdExtZfinx - : SubtargetFeature<"zfinx", "HasStdExtZfinx", "true", - "'Zfinx' (Float in Integer)", - [FeatureStdExtZicsr]>; + : RISCVExtension<"zfinx", 1, 0, + "'Zfinx' (Float in Integer)", + [FeatureStdExtZicsr]>; def HasStdExtZfinx : Predicate<"Subtarget->hasStdExtZfinx()">, AssemblerPredicate<(all_of FeatureStdExtZfinx), "'Zfinx' (Float in Integer)">; def FeatureStdExtZdinx - : SubtargetFeature<"zdinx", "HasStdExtZdinx", "true", - "'Zdinx' (Double in Integer)", - [FeatureStdExtZfinx]>; + : RISCVExtension<"zdinx", 1, 0, + "'Zdinx' (Double in Integer)", + [FeatureStdExtZfinx]>; def HasStdExtZdinx : Predicate<"Subtarget->hasStdExtZdinx()">, AssemblerPredicate<(all_of FeatureStdExtZdinx), "'Zdinx' (Double in Integer)">; def FeatureStdExtZhinxmin - : SubtargetFeature<"zhinxmin", "HasStdExtZhinxmin", "true", - "'Zhinxmin' (Half Float in Integer Minimal)", - [FeatureStdExtZfinx]>; + : RISCVExtension<"zhinxmin", 1, 0, + "'Zhinxmin' (Half Float in Integer Minimal)", + [FeatureStdExtZfinx]>; def HasStdExtZhinxmin : Predicate<"Subtarget->hasStdExtZhinxmin()">, AssemblerPredicate<(all_of FeatureStdExtZhinxmin), "'Zhinx' (Half Float in Integer) or " "'Zhinxmin' (Half Float in Integer Minimal)">; def FeatureStdExtZhinx - : SubtargetFeature<"zhinx", "HasStdExtZhinx", "true", - "'Zhinx' (Half Float in Integer)", - [FeatureStdExtZhinxmin]>; + : RISCVExtension<"zhinx", 1, 0, + "'Zhinx' (Half Float in Integer)", + [FeatureStdExtZhinxmin]>; def HasStdExtZhinx : Predicate<"Subtarget->hasStdExtZhinx()">, AssemblerPredicate<(all_of FeatureStdExtZhinx), "'Zhinx' (Half Float in Integer)">; @@ -317,8 +355,8 @@ def NoStdExtZhinx : Predicate<"!Subtarget->hasStdExtZhinx()">; // Compressed Extensions def FeatureStdExtC - : SubtargetFeature<"c", "HasStdExtC", "true", - "'C' (Compressed Instructions)">; + : RISCVExtension<"c", 2, 0, + "'C' (Compressed Instructions)">; def HasStdExtC : Predicate<"Subtarget->hasStdExtC()">, AssemblerPredicate<(all_of FeatureStdExtC), "'C' (Compressed Instructions)">; @@ -331,9 +369,9 @@ def HasRVCHints : Predicate<"Subtarget->enableRVCHintInstrs()">, "RVC Hint Instructions">; def FeatureStdExtZca - : SubtargetFeature<"zca", "HasStdExtZca", "true", - "'Zca' (part of the C extension, excluding compressed " - "floating point loads/stores)">; + : RISCVExtension<"zca", 1, 0, + "'Zca' (part of the C extension, excluding compressed " + "floating point loads/stores)">; def HasStdExtCOrZca : Predicate<"Subtarget->hasStdExtCOrZca()">, @@ -343,17 +381,17 @@ def HasStdExtCOrZca "compressed floating point loads/stores)">; def FeatureStdExtZcb - : SubtargetFeature<"zcb", "HasStdExtZcb", "true", - "'Zcb' (Compressed basic bit manipulation instructions)", - [FeatureStdExtZca]>; + : RISCVExtension<"zcb", 1, 0, + "'Zcb' (Compressed basic bit manipulation instructions)", + [FeatureStdExtZca]>; def HasStdExtZcb : Predicate<"Subtarget->hasStdExtZcb()">, AssemblerPredicate<(all_of FeatureStdExtZcb), "'Zcb' (Compressed basic bit manipulation instructions)">; def FeatureStdExtZcd - : SubtargetFeature<"zcd", "HasStdExtZcd", "true", - "'Zcd' (Compressed Double-Precision Floating-Point Instructions)", - [FeatureStdExtZca]>; + : RISCVExtension<"zcd", 1, 0, + "'Zcd' (Compressed Double-Precision Floating-Point Instructions)", + [FeatureStdExtZca]>; def HasStdExtCOrZcd : Predicate<"Subtarget->hasStdExtCOrZcd()">, @@ -362,31 +400,31 @@ def HasStdExtCOrZcd "'Zcd' (Compressed Double-Precision Floating-Point Instructions)">; def FeatureStdExtZcf - : SubtargetFeature<"zcf", "HasStdExtZcf", "true", - "'Zcf' (Compressed Single-Precision Floating-Point Instructions)", - [FeatureStdExtZca]>; + : RISCVExtension<"zcf", 1, 0, + "'Zcf' (Compressed Single-Precision Floating-Point Instructions)", + [FeatureStdExtZca]>; def FeatureStdExtZcmp - : SubtargetFeature<"zcmp", "HasStdExtZcmp", "true", - "'Zcmp' (sequenced instuctions for code-size reduction)", - [FeatureStdExtZca]>; + : RISCVExtension<"zcmp", 1, 0, + "'Zcmp' (sequenced instuctions for code-size reduction)", + [FeatureStdExtZca]>; def HasStdExtZcmp : Predicate<"Subtarget->hasStdExtZcmp() && !Subtarget->hasStdExtC()">, AssemblerPredicate<(all_of FeatureStdExtZcmp), "'Zcmp' (sequenced instuctions for code-size reduction)">; def FeatureStdExtZcmt - : SubtargetFeature<"zcmt", "HasStdExtZcmt", "true", - "'Zcmt' (table jump instuctions for code-size reduction)", - [FeatureStdExtZca, FeatureStdExtZicsr]>; + : RISCVExtension<"zcmt", 1, 0, + "'Zcmt' (table jump instuctions for code-size reduction)", + [FeatureStdExtZca, FeatureStdExtZicsr]>; def HasStdExtZcmt : Predicate<"Subtarget->hasStdExtZcmt()">, AssemblerPredicate<(all_of FeatureStdExtZcmt), "'Zcmt' (table jump instuctions for code-size reduction)">; def FeatureStdExtZce - : SubtargetFeature<"zce", "HasStdExtZce", "true", - "'Zce' (Compressed extensions for microcontrollers)", - [FeatureStdExtZca, FeatureStdExtZcb, FeatureStdExtZcmp, - FeatureStdExtZcmt]>; + : RISCVExtension<"zce", 1, 0, + "'Zce' (Compressed extensions for microcontrollers)", + [FeatureStdExtZca, FeatureStdExtZcb, FeatureStdExtZcmp, + FeatureStdExtZcmt]>; def HasStdExtCOrZcfOrZce : Predicate<"Subtarget->hasStdExtC() || Subtarget->hasStdExtZcf() " @@ -396,9 +434,10 @@ def HasStdExtCOrZcfOrZce "'C' (Compressed Instructions) or " "'Zcf' (Compressed Single-Precision Floating-Point Instructions)">; -def FeatureStdExtZcmop : SubtargetFeature<"zcmop", "HasStdExtZcmop", "true", - "'Zcmop' (Compressed May-Be-Operations)", - [FeatureStdExtZca]>; +def FeatureStdExtZcmop + : RISCVExtension<"zcmop", 1, 0, + "'Zcmop' (Compressed May-Be-Operations)", + [FeatureStdExtZca]>; def HasStdExtZcmop : Predicate<"Subtarget->hasStdExtZcmop()">, AssemblerPredicate<(all_of FeatureStdExtZcmop), "'Zcmop' (Compressed May-Be-Operations)">; @@ -406,30 +445,30 @@ def HasStdExtZcmop : Predicate<"Subtarget->hasStdExtZcmop()">, // Bitmanip Extensions def FeatureStdExtZba - : SubtargetFeature<"zba", "HasStdExtZba", "true", - "'Zba' (Address Generation Instructions)">; + : RISCVExtension<"zba", 1, 0, + "'Zba' (Address Generation Instructions)">; def HasStdExtZba : Predicate<"Subtarget->hasStdExtZba()">, AssemblerPredicate<(all_of FeatureStdExtZba), "'Zba' (Address Generation Instructions)">; def NotHasStdExtZba : Predicate<"!Subtarget->hasStdExtZba()">; def FeatureStdExtZbb - : SubtargetFeature<"zbb", "HasStdExtZbb", "true", - "'Zbb' (Basic Bit-Manipulation)">; + : RISCVExtension<"zbb", 1, 0, + "'Zbb' (Basic Bit-Manipulation)">; def HasStdExtZbb : Predicate<"Subtarget->hasStdExtZbb()">, AssemblerPredicate<(all_of FeatureStdExtZbb), "'Zbb' (Basic Bit-Manipulation)">; def FeatureStdExtZbc - : SubtargetFeature<"zbc", "HasStdExtZbc", "true", - "'Zbc' (Carry-Less Multiplication)">; + : RISCVExtension<"zbc", 1, 0, + "'Zbc' (Carry-Less Multiplication)">; def HasStdExtZbc : Predicate<"Subtarget->hasStdExtZbc()">, AssemblerPredicate<(all_of FeatureStdExtZbc), "'Zbc' (Carry-Less Multiplication)">; def FeatureStdExtZbs - : SubtargetFeature<"zbs", "HasStdExtZbs", "true", - "'Zbs' (Single-Bit Instructions)">; + : RISCVExtension<"zbs", 1, 0, + "'Zbs' (Single-Bit Instructions)">; def HasStdExtZbs : Predicate<"Subtarget->hasStdExtZbs()">, AssemblerPredicate<(all_of FeatureStdExtZbs), "'Zbs' (Single-Bit Instructions)">; @@ -437,15 +476,15 @@ def HasStdExtZbs : Predicate<"Subtarget->hasStdExtZbs()">, // Bitmanip Extensions for Cryptography Extensions def FeatureStdExtZbkb - : SubtargetFeature<"zbkb", "HasStdExtZbkb", "true", - "'Zbkb' (Bitmanip instructions for Cryptography)">; + : RISCVExtension<"zbkb", 1, 0, + "'Zbkb' (Bitmanip instructions for Cryptography)">; def HasStdExtZbkb : Predicate<"Subtarget->hasStdExtZbkb()">, AssemblerPredicate<(all_of FeatureStdExtZbkb), "'Zbkb' (Bitmanip instructions for Cryptography)">; def FeatureStdExtZbkx - : SubtargetFeature<"zbkx", "HasStdExtZbkx", "true", - "'Zbkx' (Crossbar permutation instructions)">; + : RISCVExtension<"zbkx", 1, 0, + "'Zbkx' (Crossbar permutation instructions)">; def HasStdExtZbkx : Predicate<"Subtarget->hasStdExtZbkx()">, AssemblerPredicate<(all_of FeatureStdExtZbkx), "'Zbkx' (Crossbar permutation instructions)">; @@ -460,9 +499,9 @@ def HasStdExtZbbOrZbkb // carry-less multiply subextension. The former should be enabled if the latter // is enabled. def FeatureStdExtZbkc - : SubtargetFeature<"zbkc", "HasStdExtZbkc", "true", - "'Zbkc' (Carry-less multiply instructions for " - "Cryptography)">; + : RISCVExtension<"zbkc", 1, 0, + "'Zbkc' (Carry-less multiply instructions for " + "Cryptography)">; def HasStdExtZbkc : Predicate<"Subtarget->hasStdExtZbkc()">, AssemblerPredicate<(all_of FeatureStdExtZbkc), @@ -478,15 +517,15 @@ def HasStdExtZbcOrZbkc // Cryptography Extensions def FeatureStdExtZknd - : SubtargetFeature<"zknd", "HasStdExtZknd", "true", - "'Zknd' (NIST Suite: AES Decryption)">; + : RISCVExtension<"zknd", 1, 0, + "'Zknd' (NIST Suite: AES Decryption)">; def HasStdExtZknd : Predicate<"Subtarget->hasStdExtZknd()">, AssemblerPredicate<(all_of FeatureStdExtZknd), "'Zknd' (NIST Suite: AES Decryption)">; def FeatureStdExtZkne - : SubtargetFeature<"zkne", "HasStdExtZkne", "true", - "'Zkne' (NIST Suite: AES Encryption)">; + : RISCVExtension<"zkne", 1, 0, + "'Zkne' (NIST Suite: AES Encryption)">; def HasStdExtZkne : Predicate<"Subtarget->hasStdExtZkne()">, AssemblerPredicate<(all_of FeatureStdExtZkne), "'Zkne' (NIST Suite: AES Encryption)">; @@ -500,136 +539,138 @@ def HasStdExtZkndOrZkne "'Zkne' (NIST Suite: AES Encryption)">; def FeatureStdExtZknh - : SubtargetFeature<"zknh", "HasStdExtZknh", "true", - "'Zknh' (NIST Suite: Hash Function Instructions)">; + : RISCVExtension<"zknh", 1, 0, + "'Zknh' (NIST Suite: Hash Function Instructions)">; def HasStdExtZknh : Predicate<"Subtarget->hasStdExtZknh()">, AssemblerPredicate<(all_of FeatureStdExtZknh), "'Zknh' (NIST Suite: Hash Function Instructions)">; def FeatureStdExtZksed - : SubtargetFeature<"zksed", "HasStdExtZksed", "true", - "'Zksed' (ShangMi Suite: SM4 Block Cipher Instructions)">; + : RISCVExtension<"zksed", 1, 0, + "'Zksed' (ShangMi Suite: SM4 Block Cipher Instructions)">; def HasStdExtZksed : Predicate<"Subtarget->hasStdExtZksed()">, AssemblerPredicate<(all_of FeatureStdExtZksed), "'Zksed' (ShangMi Suite: SM4 Block Cipher Instructions)">; def FeatureStdExtZksh - : SubtargetFeature<"zksh", "HasStdExtZksh", "true", - "'Zksh' (ShangMi Suite: SM3 Hash Function Instructions)">; + : RISCVExtension<"zksh", 1, 0, + "'Zksh' (ShangMi Suite: SM3 Hash Function Instructions)">; def HasStdExtZksh : Predicate<"Subtarget->hasStdExtZksh()">, AssemblerPredicate<(all_of FeatureStdExtZksh), "'Zksh' (ShangMi Suite: SM3 Hash Function Instructions)">; def FeatureStdExtZkr - : SubtargetFeature<"zkr", "HasStdExtZkr", "true", - "'Zkr' (Entropy Source Extension)">; + : RISCVExtension<"zkr", 1, 0, + "'Zkr' (Entropy Source Extension)">; def HasStdExtZkr : Predicate<"Subtarget->hasStdExtZkr()">, AssemblerPredicate<(all_of FeatureStdExtZkr), "'Zkr' (Entropy Source Extension)">; def FeatureStdExtZkn - : SubtargetFeature<"zkn", "HasStdExtZkn", "true", - "'Zkn' (NIST Algorithm Suite)", - [FeatureStdExtZbkb, - FeatureStdExtZbkc, - FeatureStdExtZbkx, - FeatureStdExtZkne, - FeatureStdExtZknd, - FeatureStdExtZknh]>; + : RISCVExtension<"zkn", 1, 0, + "'Zkn' (NIST Algorithm Suite)", + [FeatureStdExtZbkb, + FeatureStdExtZbkc, + FeatureStdExtZbkx, + FeatureStdExtZkne, + FeatureStdExtZknd, + FeatureStdExtZknh]>; def FeatureStdExtZks - : SubtargetFeature<"zks", "HasStdExtZks", "true", - "'Zks' (ShangMi Algorithm Suite)", - [FeatureStdExtZbkb, - FeatureStdExtZbkc, - FeatureStdExtZbkx, - FeatureStdExtZksed, - FeatureStdExtZksh]>; + : RISCVExtension<"zks", 1, 0, + "'Zks' (ShangMi Algorithm Suite)", + [FeatureStdExtZbkb, + FeatureStdExtZbkc, + FeatureStdExtZbkx, + FeatureStdExtZksed, + FeatureStdExtZksh]>; def FeatureStdExtZkt - : SubtargetFeature<"zkt", "HasStdExtZkt", "true", - "'Zkt' (Data Independent Execution Latency)">; + : RISCVExtension<"zkt", 1, 0, + "'Zkt' (Data Independent Execution Latency)">; def FeatureStdExtZk - : SubtargetFeature<"zk", "HasStdExtZk", "true", - "'Zk' (Standard scalar cryptography extension)", - [FeatureStdExtZkn, - FeatureStdExtZkr, - FeatureStdExtZkt]>; + : RISCVExtension<"zk", 1, 0, + "'Zk' (Standard scalar cryptography extension)", + [FeatureStdExtZkn, + FeatureStdExtZkr, + FeatureStdExtZkt]>; // Vector Extensions -def FeatureStdExtZvl32b : SubtargetFeature<"zvl32b", "ZvlLen", "32", - "'Zvl' (Minimum Vector Length) 32">; +def FeatureStdExtZvl32b : RISCVExtension<"zvl32b", 1, 0, + "'Zvl' (Minimum Vector Length) 32", [], + "ZvlLen", "32">; foreach i = { 6-16 } in { defvar I = !shl(1, i); def FeatureStdExtZvl#I#b : - SubtargetFeature<"zvl"#I#"b", "ZvlLen", !cast(I), - "'Zvl' (Minimum Vector Length) "#I, - [!cast("FeatureStdExtZvl"#!srl(I, 1)#"b")]>; + RISCVExtension<"zvl"#I#"b", 1, 0, + "'Zvl' (Minimum Vector Length) "#I, + [!cast("FeatureStdExtZvl"#!srl(I, 1)#"b")], + "ZvlLen", !cast(I)>; } def FeatureStdExtZve32x - : SubtargetFeature<"zve32x", "HasStdExtZve32x", "true", - "'Zve32x' (Vector Extensions for Embedded Processors " - "with maximal 32 EEW)", - [FeatureStdExtZicsr, FeatureStdExtZvl32b]>; + : RISCVExtension<"zve32x", 1, 0, + "'Zve32x' (Vector Extensions for Embedded Processors " + "with maximal 32 EEW)", + [FeatureStdExtZicsr, FeatureStdExtZvl32b]>; def FeatureStdExtZve32f - : SubtargetFeature<"zve32f", "HasStdExtZve32f", "true", - "'Zve32f' (Vector Extensions for Embedded Processors " - "with maximal 32 EEW and F extension)", - [FeatureStdExtZve32x, FeatureStdExtF]>; + : RISCVExtension<"zve32f", 1, 0, + "'Zve32f' (Vector Extensions for Embedded Processors " + "with maximal 32 EEW and F extension)", + [FeatureStdExtZve32x, FeatureStdExtF]>; def FeatureStdExtZve64x - : SubtargetFeature<"zve64x", "HasStdExtZve64x", "true", - "'Zve64x' (Vector Extensions for Embedded Processors " - "with maximal 64 EEW)", - [FeatureStdExtZve32x, FeatureStdExtZvl64b]>; + : RISCVExtension<"zve64x", 1, 0, + "'Zve64x' (Vector Extensions for Embedded Processors " + "with maximal 64 EEW)", + [FeatureStdExtZve32x, FeatureStdExtZvl64b]>; def FeatureStdExtZve64f - : SubtargetFeature<"zve64f", "HasStdExtZve64f", "true", - "'Zve64f' (Vector Extensions for Embedded Processors " - "with maximal 64 EEW and F extension)", - [FeatureStdExtZve32f, FeatureStdExtZve64x]>; + : RISCVExtension<"zve64f", 1, 0, + "'Zve64f' (Vector Extensions for Embedded Processors " + "with maximal 64 EEW and F extension)", + [FeatureStdExtZve32f, FeatureStdExtZve64x]>; def FeatureStdExtZve64d - : SubtargetFeature<"zve64d", "HasStdExtZve64d", "true", - "'Zve64d' (Vector Extensions for Embedded Processors " - "with maximal 64 EEW, F and D extension)", - [FeatureStdExtZve64f, FeatureStdExtD]>; + : RISCVExtension<"zve64d", 1, 0, + "'Zve64d' (Vector Extensions for Embedded Processors " + "with maximal 64 EEW, F and D extension)", + [FeatureStdExtZve64f, FeatureStdExtD]>; def FeatureStdExtV - : SubtargetFeature<"v", "HasStdExtV", "true", - "'V' (Vector Extension for Application Processors)", - [FeatureStdExtZvl128b, FeatureStdExtZve64d]>; + : RISCVExtension<"v", 1, 0, + "'V' (Vector Extension for Application Processors)", + [FeatureStdExtZvl128b, FeatureStdExtZve64d]>; def FeatureStdExtZvfbfmin - : SubtargetFeature<"experimental-zvfbfmin", "HasStdExtZvfbfmin", "true", - "'Zvbfmin' (Vector BF16 Converts)", - [FeatureStdExtZve32f]>; + : RISCVExperimentalExtension<"zvfbfmin", 1, 0, + "'Zvbfmin' (Vector BF16 Converts)", + [FeatureStdExtZve32f]>; def HasStdExtZvfbfmin : Predicate<"Subtarget->hasStdExtZvfbfmin()">, AssemblerPredicate<(all_of FeatureStdExtZvfbfmin), "'Zvfbfmin' (Vector BF16 Converts)">; def FeatureStdExtZvfbfwma - : SubtargetFeature<"experimental-zvfbfwma", "HasStdExtZvfbfwma", "true", - "'Zvfbfwma' (Vector BF16 widening mul-add)", - [FeatureStdExtZvfbfmin, FeatureStdExtZfbfmin]>; + : RISCVExperimentalExtension<"zvfbfwma", 1, 0, + "'Zvfbfwma' (Vector BF16 widening mul-add)", + [FeatureStdExtZvfbfmin, FeatureStdExtZfbfmin]>; def HasStdExtZvfbfwma : Predicate<"Subtarget->hasStdExtZvfbfwma()">, AssemblerPredicate<(all_of FeatureStdExtZvfbfwma), "'Zvfbfwma' (Vector BF16 widening mul-add)">; def FeatureStdExtZvfhmin - : SubtargetFeature<"zvfhmin", "HasStdExtZvfhmin", "true", - "'Zvfhmin' (Vector Half-Precision Floating-Point Minimal)", - [FeatureStdExtZve32f]>; + : RISCVExtension<"zvfhmin", 1, 0, + "'Zvfhmin' (Vector Half-Precision Floating-Point Minimal)", + [FeatureStdExtZve32f]>; def FeatureStdExtZvfh - : SubtargetFeature<"zvfh", "HasStdExtZvfh", "true", - "'Zvfh' (Vector Half-Precision Floating-Point)", - [FeatureStdExtZvfhmin, FeatureStdExtZfhmin]>; + : RISCVExtension<"zvfh", 1, 0, + "'Zvfh' (Vector Half-Precision Floating-Point)", + [FeatureStdExtZvfhmin, FeatureStdExtZfhmin]>; def HasStdExtZfhOrZvfh : Predicate<"Subtarget->hasStdExtZfh() || Subtarget->hasStdExtZvfh()">, @@ -640,52 +681,52 @@ def HasStdExtZfhOrZvfh // Vector Cryptography and Bitmanip Extensions def FeatureStdExtZvkb - : SubtargetFeature<"zvkb", "HasStdExtZvkb", "true", - "'Zvkb' (Vector Bit-manipulation used in Cryptography)">; + : RISCVExtension<"zvkb", 1, 0, + "'Zvkb' (Vector Bit-manipulation used in Cryptography)">; def HasStdExtZvkb : Predicate<"Subtarget->hasStdExtZvkb()">, AssemblerPredicate<(all_of FeatureStdExtZvkb), "'Zvkb' (Vector Bit-manipulation used in Cryptography)">; def FeatureStdExtZvbb - : SubtargetFeature<"zvbb", "HasStdExtZvbb", "true", - "'Zvbb' (Vector basic bit-manipulation instructions)", - [FeatureStdExtZvkb]>; + : RISCVExtension<"zvbb", 1, 0, + "'Zvbb' (Vector basic bit-manipulation instructions)", + [FeatureStdExtZvkb]>; def HasStdExtZvbb : Predicate<"Subtarget->hasStdExtZvbb()">, AssemblerPredicate<(all_of FeatureStdExtZvbb), "'Zvbb' (Vector basic bit-manipulation instructions)">; def FeatureStdExtZvbc - : SubtargetFeature<"zvbc", "HasStdExtZvbc", "true", - "'Zvbc' (Vector Carryless Multiplication)">; + : RISCVExtension<"zvbc", 1, 0, + "'Zvbc' (Vector Carryless Multiplication)">; def HasStdExtZvbc : Predicate<"Subtarget->hasStdExtZvbc()">, AssemblerPredicate<(all_of FeatureStdExtZvbc), "'Zvbc' (Vector Carryless Multiplication)">; def FeatureStdExtZvkg - : SubtargetFeature<"zvkg", "HasStdExtZvkg", "true", - "'Zvkg' (Vector GCM instructions for Cryptography)">; + : RISCVExtension<"zvkg", 1, 0, + "'Zvkg' (Vector GCM instructions for Cryptography)">; def HasStdExtZvkg : Predicate<"Subtarget->hasStdExtZvkg()">, AssemblerPredicate<(all_of FeatureStdExtZvkg), "'Zvkg' (Vector GCM instructions for Cryptography)">; def FeatureStdExtZvkned - : SubtargetFeature<"zvkned", "HasStdExtZvkned", "true", - "'Zvkned' (Vector AES Encryption & Decryption (Single Round))">; + : RISCVExtension<"zvkned", 1, 0, + "'Zvkned' (Vector AES Encryption & Decryption (Single Round))">; def HasStdExtZvkned : Predicate<"Subtarget->hasStdExtZvkned()">, AssemblerPredicate<(all_of FeatureStdExtZvkned), "'Zvkned' (Vector AES Encryption & Decryption (Single Round))">; def FeatureStdExtZvknha - : SubtargetFeature<"zvknha", "HasStdExtZvknha", "true", - "'Zvknha' (Vector SHA-2 (SHA-256 only))">; + : RISCVExtension<"zvknha", 1, 0, + "'Zvknha' (Vector SHA-2 (SHA-256 only))">; def HasStdExtZvknha : Predicate<"Subtarget->hasStdExtZvknha()">, AssemblerPredicate<(all_of FeatureStdExtZvknha), "'Zvknha' (Vector SHA-2 (SHA-256 only))">; def FeatureStdExtZvknhb - : SubtargetFeature<"zvknhb", "HasStdExtZvknhb", "true", - "'Zvknhb' (Vector SHA-2 (SHA-256 and SHA-512))", - [FeatureStdExtZve64x]>; + : RISCVExtension<"zvknhb", 1, 0, + "'Zvknhb' (Vector SHA-2 (SHA-256 and SHA-512))", + [FeatureStdExtZve64x]>; def HasStdExtZvknhb : Predicate<"Subtarget->hasStdExtZvknhb()">, AssemblerPredicate<(all_of FeatureStdExtZvknhb), "'Zvknhb' (Vector SHA-2 (SHA-256 and SHA-512))">; @@ -695,58 +736,58 @@ def HasStdExtZvknhaOrZvknhb : Predicate<"Subtarget->hasStdExtZvknha() || Subtarg "'Zvknha' or 'Zvknhb' (Vector SHA-2)">; def FeatureStdExtZvksed - : SubtargetFeature<"zvksed", "HasStdExtZvksed", "true", - "'Zvksed' (SM4 Block Cipher Instructions)">; + : RISCVExtension<"zvksed", 1, 0, + "'Zvksed' (SM4 Block Cipher Instructions)">; def HasStdExtZvksed : Predicate<"Subtarget->hasStdExtZvksed()">, AssemblerPredicate<(all_of FeatureStdExtZvksed), "'Zvksed' (SM4 Block Cipher Instructions)">; def FeatureStdExtZvksh - : SubtargetFeature<"zvksh", "HasStdExtZvksh", "true", - "'Zvksh' (SM3 Hash Function Instructions)">; + : RISCVExtension<"zvksh", 1, 0, + "'Zvksh' (SM3 Hash Function Instructions)">; def HasStdExtZvksh : Predicate<"Subtarget->hasStdExtZvksh()">, AssemblerPredicate<(all_of FeatureStdExtZvksh), "'Zvksh' (SM3 Hash Function Instructions)">; def FeatureStdExtZvkt - : SubtargetFeature<"zvkt", "HasStdExtZvkt", "true", - "'Zvkt' (Vector Data-Independent Execution Latency)">; + : RISCVExtension<"zvkt", 1, 0, + "'Zvkt' (Vector Data-Independent Execution Latency)">; // Zvk short-hand extensions def FeatureStdExtZvkn - : SubtargetFeature<"zvkn", "HasStdExtZvkn", "true", - "'Zvkn' (shorthand for 'Zvkned', 'Zvknhb', 'Zvkb', and " - "'Zvkt')", - [FeatureStdExtZvkned, FeatureStdExtZvknhb, - FeatureStdExtZvkb, FeatureStdExtZvkt]>; + : RISCVExtension<"zvkn", 1, 0, + "'Zvkn' (shorthand for 'Zvkned', 'Zvknhb', 'Zvkb', and " + "'Zvkt')", + [FeatureStdExtZvkned, FeatureStdExtZvknhb, + FeatureStdExtZvkb, FeatureStdExtZvkt]>; def FeatureStdExtZvknc - : SubtargetFeature<"zvknc", "HasStdExtZvknc", "true", - "'Zvknc' (shorthand for 'Zvknc' and 'Zvbc')", - [FeatureStdExtZvkn, FeatureStdExtZvbc]>; + : RISCVExtension<"zvknc", 1, 0, + "'Zvknc' (shorthand for 'Zvknc' and 'Zvbc')", + [FeatureStdExtZvkn, FeatureStdExtZvbc]>; def FeatureStdExtZvkng - : SubtargetFeature<"zvkng", "HasStdExtZvkng", "true", - "'zvkng' (shorthand for 'Zvkn' and 'Zvkg')", - [FeatureStdExtZvkn, FeatureStdExtZvkg]>; + : RISCVExtension<"zvkng", 1, 0, + "'zvkng' (shorthand for 'Zvkn' and 'Zvkg')", + [FeatureStdExtZvkn, FeatureStdExtZvkg]>; def FeatureStdExtZvks - : SubtargetFeature<"zvks", "HasStdExtZvks", "true", - "'Zvks' (shorthand for 'Zvksed', 'Zvksh', 'Zvkb', and " - "'Zvkt')", - [FeatureStdExtZvksed, FeatureStdExtZvksh, - FeatureStdExtZvkb, FeatureStdExtZvkt]>; + : RISCVExtension<"zvks", 1, 0, + "'Zvks' (shorthand for 'Zvksed', 'Zvksh', 'Zvkb', and " + "'Zvkt')", + [FeatureStdExtZvksed, FeatureStdExtZvksh, + FeatureStdExtZvkb, FeatureStdExtZvkt]>; def FeatureStdExtZvksc - : SubtargetFeature<"zvksc", "HasStdExtZvksc", "true", - "'Zvksc' (shorthand for 'Zvks' and 'Zvbc')", - [FeatureStdExtZvks, FeatureStdExtZvbc]>; + : RISCVExtension<"zvksc", 1, 0, + "'Zvksc' (shorthand for 'Zvks' and 'Zvbc')", + [FeatureStdExtZvks, FeatureStdExtZvbc]>; def FeatureStdExtZvksg - : SubtargetFeature<"zvksg", "HasStdExtZvksg", "true", - "'Zvksg' (shorthand for 'Zvks' and 'Zvkg')", - [FeatureStdExtZvks, FeatureStdExtZvkg]>; + : RISCVExtension<"zvksg", 1, 0, + "'Zvksg' (shorthand for 'Zvks' and 'Zvkg')", + [FeatureStdExtZvks, FeatureStdExtZvkg]>; // Vector instruction predicates @@ -780,8 +821,8 @@ def HasVInstructionsFullMultiply : Predicate<"Subtarget->hasVInstructionsFullMul // Hypervisor Extensions def FeatureStdExtH - : SubtargetFeature<"h", "HasStdExtH", "true", - "'H' (Hypervisor)">; + : RISCVExtension<"h", 1, 0, + "'H' (Hypervisor)">; def HasStdExtH : Predicate<"Subtarget->hasStdExtH()">, AssemblerPredicate<(all_of FeatureStdExtH), @@ -790,105 +831,104 @@ def HasStdExtH : Predicate<"Subtarget->hasStdExtH()">, // Supervisor extensions def FeatureStdExtShgatpa - : SubtargetFeature<"shgatpa", "HasStdExtShgatpa", "true", - "'Sgatpa' (SvNNx4 mode supported for all modes supported by satp, as well as Bare)", []>; + : RISCVExtension<"shgatpa", 1, 0, + "'Sgatpa' (SvNNx4 mode supported for all modes supported by satp, as well as Bare)">; def FeatureStdExtShvsatpa - : SubtargetFeature<"shvsatpa", "HasStdExtSvsatpa", "true", - "'Svsatpa' (vsatp supports all modes supported by satp)", []>; + : RISCVExtension<"shvsatpa", 1, 0, + "'Svsatpa' (vsatp supports all modes supported by satp)">; def FeatureStdExtSmaia - : SubtargetFeature<"smaia", "HasStdExtSmaia", "true", - "'Smaia' (Advanced Interrupt Architecture Machine " - "Level)", []>; + : RISCVExtension<"smaia", 1, 0, + "'Smaia' (Advanced Interrupt Architecture Machine Level)">; def FeatureStdExtSsaia - : SubtargetFeature<"ssaia", "HasStdExtSsaia", "true", - "'Ssaia' (Advanced Interrupt Architecture Supervisor " - "Level)", []>; + : RISCVExtension<"ssaia", 1, 0, + "'Ssaia' (Advanced Interrupt Architecture Supervisor " + "Level)">; def FeatureStdExtSmepmp - : SubtargetFeature<"smepmp", "HasStdExtSmepmp", "true", - "'Smepmp' (Enhanced Physical Memory Protection)", []>; + : RISCVExtension<"smepmp", 1, 0, + "'Smepmp' (Enhanced Physical Memory Protection)">; def FeatureStdExtSsccptr - : SubtargetFeature<"ssccptr", "HasStdExtSsccptr", "true", - "'Ssccptr' (Main memory supports page table reads)", []>; + : RISCVExtension<"ssccptr", 1, 0, + "'Ssccptr' (Main memory supports page table reads)">; def FeatureStdExtSscofpmf - : SubtargetFeature<"sscofpmf", "HasStdExtSscofpmf", "true", - "'Sscofpmf' (Count Overflow and Mode-Based Filtering)", []>; + : RISCVExtension<"sscofpmf", 1, 0, + "'Sscofpmf' (Count Overflow and Mode-Based Filtering)">; def FeatureStdExtShcounterenw - : SubtargetFeature<"shcounterenw", "HasStdExtShcounterenw", "true", - "'Shcounterenw' (Support writeable hcounteren enable " - "bit for any hpmcounter that is not read-only zero)", []>; + : RISCVExtension<"shcounterenw", 1, 0, + "'Shcounterenw' (Support writeable hcounteren enable " + "bit for any hpmcounter that is not read-only zero)">; def FeatureStdExtSscounterenw - : SubtargetFeature<"sscounterenw", "HasStdExtSscounterenw", "true", - "'Sscounterenw' (Support writeable scounteren enable " - "bit for any hpmcounter that is not read-only zero)", []>; + : RISCVExtension<"sscounterenw", 1, 0, + "'Sscounterenw' (Support writeable scounteren enable " + "bit for any hpmcounter that is not read-only zero)">; def FeatureStdExtSsstateen - : SubtargetFeature<"ssstateen", "HasStdExtSsstateen", "true", - "'Ssstateen' (Supervisor-mode view of the state-enable extension)", []>; + : RISCVExtension<"ssstateen", 1, 0, + "'Ssstateen' (Supervisor-mode view of the state-enable extension)">; def FeatureStdExtSsstrict - : SubtargetFeature<"ssstrict", "HasStdExtSsstrict", "true", - "'Ssstrict' (No non-conforming extensions are present)", []>; + : RISCVExtension<"ssstrict", 1, 0, + "'Ssstrict' (No non-conforming extensions are present)">; def FeatureStdExtSstc - : SubtargetFeature<"sstc", "HasStdExtSstc", "true", - "'Sstc' (Supervisor-mode timer interrupts)", []>; + : RISCVExtension<"sstc", 1, 0, + "'Sstc' (Supervisor-mode timer interrupts)">; def FeaturesSsqosid - : SubtargetFeature<"experimental-ssqosid", "HasStdExtSsqosid", "true", - "'Ssqosid' (Quality-of-Service (QoS) Identifiers)", []>; + : RISCVExperimentalExtension<"ssqosid", 1, 0, + "'Ssqosid' (Quality-of-Service (QoS) Identifiers)">; def FeatureStdExtShtvala - : SubtargetFeature<"shtvala", "HasStdExtShtvala", "true", - "'Shtvala' (htval provides all needed values)", []>; + : RISCVExtension<"shtvala", 1, 0, + "'Shtvala' (htval provides all needed values)">; def FeatureStdExtShvstvala - : SubtargetFeature<"shvstvala", "HasStdExtShvstvala", "true", - "'Shvstvala' (vstval provides all needed values)", []>; + : RISCVExtension<"shvstvala", 1, 0, + "'Shvstvala' (vstval provides all needed values)">; def FeatureStdExtSstvala - : SubtargetFeature<"sstvala", "HasStdExtSstvala", "true", - "'Sstvala' (stval provides all needed values)", []>; + : RISCVExtension<"sstvala", 1, 0, + "'Sstvala' (stval provides all needed values)">; def FeatureStdExtShvstvecd - : SubtargetFeature<"shvstvecd", "HasStdExtShvstvecd", "true", - "'Shvstvecd' (vstvec supports Direct mode)", []>; + : RISCVExtension<"shvstvecd", 1, 0, + "'Shvstvecd' (vstvec supports Direct mode)">; def FeatureStdExtSstvecd - : SubtargetFeature<"sstvecd", "HasStdExtSstvecd", "true", - "'Sstvecd' (stvec supports Direct mode)", []>; + : RISCVExtension<"sstvecd", 1, 0, + "'Sstvecd' (stvec supports Direct mode)">; def FeatureStdExtSsu64xl - : SubtargetFeature<"ssu64xl", "HasStdExtSsu64xl", "true", - "'Ssu64xl' (UXLEN=64 supported)", []>; + : RISCVExtension<"ssu64xl", 1, 0, + "'Ssu64xl' (UXLEN=64 supported)">; def FeatureStdExtSvade - : SubtargetFeature<"svade", "HasStdExtSvade", "true", - "'Svade' (Raise exceptions on improper A/D bits)", []>; + : RISCVExtension<"svade", 1, 0, + "'Svade' (Raise exceptions on improper A/D bits)">; def FeatureStdExtSvadu - : SubtargetFeature<"svadu", "HasStdExtSvadu", "true", - "'Svadu' (Hardware A/D updates)", []>; + : RISCVExtension<"svadu", 1, 0, + "'Svadu' (Hardware A/D updates)">; def FeatureStdExtSvbare - : SubtargetFeature<"svbare", "HasStdExtSvbare", "true", - "'Svbare' $(satp mode Bare supported)", []>; + : RISCVExtension<"svbare", 1, 0, + "'Svbare' $(satp mode Bare supported)">; def FeatureStdExtSvinval - : SubtargetFeature<"svinval", "HasStdExtSvinval", "true", - "'Svinval' (Fine-Grained Address-Translation Cache Invalidation)">; + : RISCVExtension<"svinval", 1, 0, + "'Svinval' (Fine-Grained Address-Translation Cache Invalidation)">; def HasStdExtSvinval : Predicate<"Subtarget->hasStdExtSvinval()">, AssemblerPredicate<(all_of FeatureStdExtSvinval), "'Svinval' (Fine-Grained Address-Translation Cache Invalidation)">; def FeatureStdExtSvnapot - : SubtargetFeature<"svnapot", "HasStdExtSvnapot", "true", - "'Svnapot' (NAPOT Translation Contiguity)">; + : RISCVExtension<"svnapot", 1, 0, + "'Svnapot' (NAPOT Translation Contiguity)">; def FeatureStdExtSvpbmt - : SubtargetFeature<"svpbmt", "HasStdExtSvpbmt", "true", - "'Svpbmt' (Page-Based Memory Types)">; + : RISCVExtension<"svpbmt", 1, 0, + "'Svpbmt' (Page-Based Memory Types)">; // Pointer Masking extensions @@ -896,33 +936,33 @@ def FeatureStdExtSvpbmt // privilege mode (U-mode), and for VS- and VU-modes if the H extension is // present. def FeatureStdExtSsnpm - : SubtargetFeature<"experimental-ssnpm", "HasStdExtSsnpm", "true", - "'Ssnpm' (Supervisor-level Pointer Masking for next lower privilege mode)">; + : RISCVExperimentalExtension<"ssnpm", 0, 8, + "'Ssnpm' (Supervisor-level Pointer Masking for next lower privilege mode)">; // A machine-level extension that provides pointer masking for the next lower // privilege mode (S/HS if S-mode is implemented, or U-mode otherwise). def FeatureStdExtSmnpm - : SubtargetFeature<"experimental-smnpm", "HasStdExtSmnpm", "true", - "'Smnpm' (Machine-level Pointer Masking for next lower privilege mode)">; + : RISCVExperimentalExtension<"smnpm", 0, 8, + "'Smnpm' (Machine-level Pointer Masking for next lower privilege mode)">; // A machine-level extension that provides pointer masking for M-mode. def FeatureStdExtSmmpm - : SubtargetFeature<"experimental-smmpm", "HasStdExtSmmpm", "true", - "'Smmpm' (Machine-level Pointer Masking for M-mode)">; + : RISCVExperimentalExtension<"smmpm", 0, 8, + "'Smmpm' (Machine-level Pointer Masking for M-mode)">; // An extension that indicates that there is pointer-masking support available // in supervisor mode, with some facility provided in the supervisor execution // environment to control pointer masking. def FeatureStdExtSspm - : SubtargetFeature<"experimental-sspm", "HasStdExtSspm", "true", - "'Sspm' (Indicates Supervisor-mode Pointer Masking)">; + : RISCVExperimentalExtension<"sspm", 0, 8, + "'Sspm' (Indicates Supervisor-mode Pointer Masking)">; // An extension that indicates that there is pointer-masking support available // in user mode, with some facility provided in the application execution // environment to control pointer masking. def FeatureStdExtSupm - : SubtargetFeature<"experimental-supm", "HasStdExtSupm", "true", - "'Supm' (Indicates User-mode Pointer Masking)">; + : RISCVExperimentalExtension<"supm", 0, 8, + "'Supm' (Indicates User-mode Pointer Masking)">; //===----------------------------------------------------------------------===// // Vendor extensions @@ -931,8 +971,8 @@ def FeatureStdExtSupm // Ventana Extenions def FeatureVendorXVentanaCondOps - : SubtargetFeature<"xventanacondops", "HasVendorXVentanaCondOps", "true", - "'XVentanaCondOps' (Ventana Conditional Ops)">; + : RISCVExtension<"xventanacondops", 1, 0, + "'XVentanaCondOps' (Ventana Conditional Ops)">; def HasVendorXVentanaCondOps : Predicate<"Subtarget->hasVendorXVentanaCondOps()">, AssemblerPredicate<(all_of FeatureVendorXVentanaCondOps), "'XVentanaCondOps' (Ventana Conditional Ops)">; @@ -940,80 +980,80 @@ def HasVendorXVentanaCondOps : Predicate<"Subtarget->hasVendorXVentanaCondOps()" // T-Head Extensions def FeatureVendorXTHeadBa - : SubtargetFeature<"xtheadba", "HasVendorXTHeadBa", "true", - "'xtheadba' (T-Head address calculation instructions)">; + : RISCVExtension<"xtheadba", 1, 0, + "'xtheadba' (T-Head address calculation instructions)">; def HasVendorXTHeadBa : Predicate<"Subtarget->hasVendorXTHeadBa()">, AssemblerPredicate<(all_of FeatureVendorXTHeadBa), "'xtheadba' (T-Head address calculation instructions)">; def FeatureVendorXTHeadBb - : SubtargetFeature<"xtheadbb", "HasVendorXTHeadBb", "true", - "'xtheadbb' (T-Head basic bit-manipulation instructions)">; + : RISCVExtension<"xtheadbb", 1, 0, + "'xtheadbb' (T-Head basic bit-manipulation instructions)">; def HasVendorXTHeadBb : Predicate<"Subtarget->hasVendorXTHeadBb()">, AssemblerPredicate<(all_of FeatureVendorXTHeadBb), "'xtheadbb' (T-Head basic bit-manipulation instructions)">; def FeatureVendorXTHeadBs - : SubtargetFeature<"xtheadbs", "HasVendorXTHeadBs", "true", - "'xtheadbs' (T-Head single-bit instructions)">; + : RISCVExtension<"xtheadbs", 1, 0, + "'xtheadbs' (T-Head single-bit instructions)">; def HasVendorXTHeadBs : Predicate<"Subtarget->hasVendorXTHeadBs()">, AssemblerPredicate<(all_of FeatureVendorXTHeadBs), "'xtheadbs' (T-Head single-bit instructions)">; def FeatureVendorXTHeadCondMov - : SubtargetFeature<"xtheadcondmov", "HasVendorXTHeadCondMov", "true", - "'xtheadcondmov' (T-Head conditional move instructions)">; + : RISCVExtension<"xtheadcondmov", 1, 0, + "'xtheadcondmov' (T-Head conditional move instructions)">; def HasVendorXTHeadCondMov : Predicate<"Subtarget->hasVendorXTHeadCondMov()">, AssemblerPredicate<(all_of FeatureVendorXTHeadCondMov), "'xtheadcondmov' (T-Head conditional move instructions)">; def FeatureVendorXTHeadCmo - : SubtargetFeature<"xtheadcmo", "HasVendorXTHeadCmo", "true", - "'xtheadcmo' (T-Head cache management instructions)">; + : RISCVExtension<"xtheadcmo", 1, 0, + "'xtheadcmo' (T-Head cache management instructions)">; def HasVendorXTHeadCmo : Predicate<"Subtarget->hasVendorXTHeadCmo()">, AssemblerPredicate<(all_of FeatureVendorXTHeadCmo), "'xtheadcmo' (T-Head cache management instructions)">; def FeatureVendorXTHeadFMemIdx - : SubtargetFeature<"xtheadfmemidx", "HasVendorXTHeadFMemIdx", "true", - "'xtheadfmemidx' (T-Head FP Indexed Memory Operations)", - [FeatureStdExtF]>; + : RISCVExtension<"xtheadfmemidx", 1, 0, + "'xtheadfmemidx' (T-Head FP Indexed Memory Operations)", + [FeatureStdExtF]>; def HasVendorXTHeadFMemIdx : Predicate<"Subtarget->hasVendorXTHeadFMemIdx()">, AssemblerPredicate<(all_of FeatureVendorXTHeadFMemIdx), "'xtheadfmemidx' (T-Head FP Indexed Memory Operations)">; def FeatureVendorXTHeadMac - : SubtargetFeature<"xtheadmac", "HasVendorXTHeadMac", "true", - "'xtheadmac' (T-Head Multiply-Accumulate Instructions)">; + : RISCVExtension<"xtheadmac", 1, 0, + "'xtheadmac' (T-Head Multiply-Accumulate Instructions)">; def HasVendorXTHeadMac : Predicate<"Subtarget->hasVendorXTHeadMac()">, AssemblerPredicate<(all_of FeatureVendorXTHeadMac), "'xtheadmac' (T-Head Multiply-Accumulate Instructions)">; def FeatureVendorXTHeadMemIdx - : SubtargetFeature<"xtheadmemidx", "HasVendorXTHeadMemIdx", "true", - "'xtheadmemidx' (T-Head Indexed Memory Operations)">; + : RISCVExtension<"xtheadmemidx", 1, 0, + "'xtheadmemidx' (T-Head Indexed Memory Operations)">; def HasVendorXTHeadMemIdx : Predicate<"Subtarget->hasVendorXTHeadMemIdx()">, AssemblerPredicate<(all_of FeatureVendorXTHeadMemIdx), "'xtheadmemidx' (T-Head Indexed Memory Operations)">; def FeatureVendorXTHeadMemPair - : SubtargetFeature<"xtheadmempair", "HasVendorXTHeadMemPair", "true", - "'xtheadmempair' (T-Head two-GPR Memory Operations)">; + : RISCVExtension<"xtheadmempair", 1, 0, + "'xtheadmempair' (T-Head two-GPR Memory Operations)">; def HasVendorXTHeadMemPair : Predicate<"Subtarget->hasVendorXTHeadMemPair()">, AssemblerPredicate<(all_of FeatureVendorXTHeadMemPair), "'xtheadmempair' (T-Head two-GPR Memory Operations)">; def FeatureVendorXTHeadSync - : SubtargetFeature<"xtheadsync", "HasVendorXTHeadSync", "true", - "'xtheadsync' (T-Head multicore synchronization instructions)">; + : RISCVExtension<"xtheadsync", 1, 0, + "'xtheadsync' (T-Head multicore synchronization instructions)">; def HasVendorXTHeadSync : Predicate<"Subtarget->hasVendorXTHeadSync()">, AssemblerPredicate<(all_of FeatureVendorXTHeadSync), "'xtheadsync' (T-Head multicore synchronization instructions)">; def FeatureVendorXTHeadVdot - : SubtargetFeature<"xtheadvdot", "HasVendorXTHeadVdot", "true", - "'xtheadvdot' (T-Head Vector Extensions for Dot)", - [FeatureStdExtV]>; + : RISCVExtension<"xtheadvdot", 1, 0, + "'xtheadvdot' (T-Head Vector Extensions for Dot)", + [FeatureStdExtV]>; def HasVendorXTHeadVdot : Predicate<"Subtarget->hasVendorXTHeadVdot()">, AssemblerPredicate<(all_of FeatureVendorXTHeadVdot), "'xtheadvdot' (T-Head Vector Extensions for Dot)">; @@ -1021,68 +1061,68 @@ def HasVendorXTHeadVdot : Predicate<"Subtarget->hasVendorXTHeadVdot()">, // SiFive Extensions def FeatureVendorXSfvcp - : SubtargetFeature<"xsfvcp", "HasVendorXSfvcp", "true", - "'XSfvcp' (SiFive Custom Vector Coprocessor Interface Instructions)", - [FeatureStdExtZve32x]>; + : RISCVExtension<"xsfvcp", 1, 0, + "'XSfvcp' (SiFive Custom Vector Coprocessor Interface Instructions)", + [FeatureStdExtZve32x]>; def HasVendorXSfvcp : Predicate<"Subtarget->hasVendorXSfvcp()">, AssemblerPredicate<(all_of FeatureVendorXSfvcp), "'XSfvcp' (SiFive Custom Vector Coprocessor Interface Instructions)">; def FeatureVendorXSfvqmaccdod - : SubtargetFeature<"xsfvqmaccdod", "HasVendorXSfvqmaccdod", "true", - "'XSfvqmaccdod' (SiFive Int8 Matrix Multiplication Instructions (2-by-8 and 8-by-2))", - [FeatureStdExtZve32x]>; + : RISCVExtension<"xsfvqmaccdod", 1, 0, + "'XSfvqmaccdod' (SiFive Int8 Matrix Multiplication Instructions (2-by-8 and 8-by-2))", + [FeatureStdExtZve32x]>; def HasVendorXSfvqmaccdod : Predicate<"Subtarget->hasVendorXSfvqmaccdod()">, AssemblerPredicate<(all_of FeatureVendorXSfvqmaccdod), "'XSfvqmaccdod' (SiFive Int8 Matrix Multiplication Instructions (2-by-8 and 8-by-2))">; def FeatureVendorXSfvqmaccqoq - : SubtargetFeature<"xsfvqmaccqoq", "HasVendorXSfvqmaccqoq", "true", - "'XSfvqmaccqoq' (SiFive Int8 Matrix Multiplication Instructions (4-by-8 and 8-by-4))", - [FeatureStdExtZve32x]>; + : RISCVExtension<"xsfvqmaccqoq", 1, 0, + "'XSfvqmaccqoq' (SiFive Int8 Matrix Multiplication Instructions (4-by-8 and 8-by-4))", + [FeatureStdExtZve32x]>; def HasVendorXSfvqmaccqoq : Predicate<"Subtarget->hasVendorXSfvqmaccqoq()">, AssemblerPredicate<(all_of FeatureVendorXSfvqmaccqoq), "'XSfvqmaccqoq' (SiFive Int8 Matrix Multiplication Instructions (4-by-8 and 8-by-4))">; def FeatureVendorXSfvfwmaccqqq - : SubtargetFeature<"xsfvfwmaccqqq", "HasVendorXSfvfwmaccqqq", "true", - "'XSfvfwmaccqqq' (SiFive Matrix Multiply Accumulate Instruction and 4-by-4))", - [FeatureStdExtZve32f, FeatureStdExtZvfbfmin]>; + : RISCVExtension<"xsfvfwmaccqqq", 1, 0, + "'XSfvfwmaccqqq' (SiFive Matrix Multiply Accumulate Instruction and 4-by-4))", + [FeatureStdExtZve32f, FeatureStdExtZvfbfmin]>; def HasVendorXSfvfwmaccqqq : Predicate<"Subtarget->hasVendorXSfvfwmaccqqq()">, AssemblerPredicate<(all_of FeatureVendorXSfvfwmaccqqq), "'XSfvfwmaccqqq' (SiFive Matrix Multiply Accumulate Instruction and 4-by-4))">; def FeatureVendorXSfvfnrclipxfqf - : SubtargetFeature<"xsfvfnrclipxfqf", "HasVendorXSfvfnrclipxfqf", "true", - "'XSfvfnrclipxfqf' (SiFive FP32-to-int8 Ranged Clip Instructions)", - [FeatureStdExtZve32f]>; + : RISCVExtension<"xsfvfnrclipxfqf", 1, 0, + "'XSfvfnrclipxfqf' (SiFive FP32-to-int8 Ranged Clip Instructions)", + [FeatureStdExtZve32f]>; def HasVendorXSfvfnrclipxfqf : Predicate<"Subtarget->hasVendorXSfvfnrclipxfqf()">, AssemblerPredicate<(all_of FeatureVendorXSfvfnrclipxfqf), "'XSfvfnrclipxfqf' (SiFive FP32-to-int8 Ranged Clip Instructions)">; def FeatureVendorXSiFivecdiscarddlone - : SubtargetFeature<"xsifivecdiscarddlone", "HasVendorXSiFivecdiscarddlone", "true", - "'XSiFivecdiscarddlone' (SiFive sf.cdiscard.d.l1 Instruction)", []>; + : RISCVExtension<"xsifivecdiscarddlone", 1, 0, + "'XSiFivecdiscarddlone' (SiFive sf.cdiscard.d.l1 Instruction)", []>; def HasVendorXSiFivecdiscarddlone : Predicate<"Subtarget->hasVendorXSiFivecdiscarddlone()">, AssemblerPredicate<(all_of FeatureVendorXSiFivecdiscarddlone), "'XSiFivecdiscarddlone' (SiFive sf.cdiscard.d.l1 Instruction)">; def FeatureVendorXSiFivecflushdlone - : SubtargetFeature<"xsifivecflushdlone", "HasVendorXSiFivecflushdlone", "true", - "'XSiFivecflushdlone' (SiFive sf.cflush.d.l1 Instruction)", []>; + : RISCVExtension<"xsifivecflushdlone", 1, 0, + "'XSiFivecflushdlone' (SiFive sf.cflush.d.l1 Instruction)", []>; def HasVendorXSiFivecflushdlone : Predicate<"Subtarget->hasVendorXSiFivecflushdlone()">, AssemblerPredicate<(all_of FeatureVendorXSiFivecflushdlone), "'XSiFivecflushdlone' (SiFive sf.cflush.d.l1 Instruction)">; def FeatureVendorXSfcease - : SubtargetFeature<"xsfcease", "HasVendorXSfcease", "true", - "'XSfcease' (SiFive sf.cease Instruction)", []>; + : RISCVExtension<"xsfcease", 1, 0, + "'XSfcease' (SiFive sf.cease Instruction)", []>; def HasVendorXSfcease : Predicate<"Subtarget->hasVendorXSfcease()">, AssemblerPredicate<(all_of FeatureVendorXSfcease), @@ -1091,56 +1131,56 @@ def HasVendorXSfcease // Core-V Extensions def FeatureVendorXCVelw - : SubtargetFeature<"xcvelw", "HasVendorXCVelw", "true", - "'XCVelw' (CORE-V Event Load Word)">; + : RISCVExtension<"xcvelw", 1, 0, + "'XCVelw' (CORE-V Event Load Word)">; def HasVendorXCVelw : Predicate<"Subtarget->hasVendorXCVelw()">, AssemblerPredicate<(any_of FeatureVendorXCVelw), "'XCVelw' (CORE-V Event Load Word)">; def FeatureVendorXCVbitmanip - : SubtargetFeature<"xcvbitmanip", "HasVendorXCVbitmanip", "true", - "'XCVbitmanip' (CORE-V Bit Manipulation)">; + : RISCVExtension<"xcvbitmanip", 1, 0, + "'XCVbitmanip' (CORE-V Bit Manipulation)">; def HasVendorXCVbitmanip : Predicate<"Subtarget->hasVendorXCVbitmanip()">, AssemblerPredicate<(all_of FeatureVendorXCVbitmanip), "'XCVbitmanip' (CORE-V Bit Manipulation)">; def FeatureVendorXCVmac - : SubtargetFeature<"xcvmac", "HasVendorXCVmac", "true", - "'XCVmac' (CORE-V Multiply-Accumulate)">; + : RISCVExtension<"xcvmac", 1, 0, + "'XCVmac' (CORE-V Multiply-Accumulate)">; def HasVendorXCVmac : Predicate<"Subtarget->hasVendorXCVmac()">, AssemblerPredicate<(all_of FeatureVendorXCVmac), "'XCVmac' (CORE-V Multiply-Accumulate)">; def FeatureVendorXCVmem - : SubtargetFeature<"xcvmem", "HasVendorXCVmem", "true", - "'XCVmem' (CORE-V Post-incrementing Load & Store)">; + : RISCVExtension<"xcvmem", 1, 0, + "'XCVmem' (CORE-V Post-incrementing Load & Store)">; def HasVendorXCVmem : Predicate<"Subtarget->hasVendorXCVmem()">, AssemblerPredicate<(any_of FeatureVendorXCVmem), "'XCVmem' (CORE-V Post-incrementing Load & Store)">; def FeatureVendorXCValu - : SubtargetFeature<"xcvalu", "HasVendorXCValu", "true", - "'XCValu' (CORE-V ALU Operations)">; + : RISCVExtension<"xcvalu", 1, 0, + "'XCValu' (CORE-V ALU Operations)">; def HasVendorXCValu : Predicate<"Subtarget->hasVendorXCValu()">, AssemblerPredicate<(all_of FeatureVendorXCValu), "'XCValu' (CORE-V ALU Operations)">; def FeatureVendorXCVsimd - : SubtargetFeature<"xcvsimd", "HasVendorXCvsimd", "true", - "'XCVsimd' (CORE-V SIMD ALU)">; + : RISCVExtension<"xcvsimd", 1, 0, + "'XCVsimd' (CORE-V SIMD ALU)">; def HasVendorXCVsimd : Predicate<"Subtarget->hasVendorXCVsimd()">, AssemblerPredicate<(any_of FeatureVendorXCVsimd), "'XCVsimd' (CORE-V SIMD ALU)">; def FeatureVendorXCVbi - : SubtargetFeature<"xcvbi", "HasVendorXCVbi", "true", - "'XCVbi' (CORE-V Immediate Branching)">; + : RISCVExtension<"xcvbi", 1, 0, + "'XCVbi' (CORE-V Immediate Branching)">; def HasVendorXCVbi : Predicate<"Subtarget->hasVendorXCVbi()">, AssemblerPredicate<(all_of FeatureVendorXCVbi), -- GitLab From c1b6cca1214e7a9c14a30b81585dd8b81baeaa77 Mon Sep 17 00:00:00 2001 From: Wentao Zhang <35722712+whentojump@users.noreply.github.com> Date: Mon, 22 Apr 2024 12:37:38 -0500 Subject: [PATCH 011/732] [clang][CoverageMapping] do not emit a gap region when either end doesn't have valid source locations (#89564) Fixes #86998 --- clang/lib/CodeGen/CoverageMappingGen.cpp | 11 ++++-- .../CoverageMapping/statement-expression.c | 36 +++++++++++++++++++ 2 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 clang/test/CoverageMapping/statement-expression.c diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp index 64c39c5de351..733686d4946b 100644 --- a/clang/lib/CodeGen/CoverageMappingGen.cpp +++ b/clang/lib/CodeGen/CoverageMappingGen.cpp @@ -1208,6 +1208,12 @@ struct CounterCoverageMappingBuilder /// Find a valid gap range between \p AfterLoc and \p BeforeLoc. std::optional findGapAreaBetween(SourceLocation AfterLoc, SourceLocation BeforeLoc) { + // Some statements (like AttributedStmt and ImplicitValueInitExpr) don't + // have valid source locations. Do not emit a gap region if this is the case + // in either AfterLoc end or BeforeLoc end. + if (AfterLoc.isInvalid() || BeforeLoc.isInvalid()) + return std::nullopt; + // If AfterLoc is in function-like macro, use the right parenthesis // location. if (AfterLoc.isMacroID()) { @@ -1368,9 +1374,8 @@ struct CounterCoverageMappingBuilder for (const Stmt *Child : S->children()) if (Child) { // If last statement contains terminate statements, add a gap area - // between the two statements. Skipping attributed statements, because - // they don't have valid start location. - if (LastStmt && HasTerminateStmt && !isa(Child)) { + // between the two statements. + if (LastStmt && HasTerminateStmt) { auto Gap = findGapAreaBetween(getEnd(LastStmt), getStart(Child)); if (Gap) fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), diff --git a/clang/test/CoverageMapping/statement-expression.c b/clang/test/CoverageMapping/statement-expression.c new file mode 100644 index 000000000000..5f9ab5838af3 --- /dev/null +++ b/clang/test/CoverageMapping/statement-expression.c @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -mllvm -emptyline-comment-coverage=false -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -emit-llvm-only -main-file-name statement-expression.c %s + +// No crash for the following examples, where GNU Statement Expression extension +// could introduce region terminators (break, goto etc) before implicit +// initializers in a struct or an array. +// See https://github.com/llvm/llvm-project/pull/89564 + +struct Foo { + int field1; + int field2; +}; + +void f1(void) { + struct Foo foo = { + .field1 = ({ + switch (0) { + case 0: + break; // A region terminator + } + 0; + }), + // ImplicitValueInitExpr introduced here for .field2 + }; +} + +void f2(void) { + int arr[3] = { + [0] = ({ + goto L0; // A region terminator +L0: + 0; + }), + // ImplicitValueInitExpr introduced here for subscript [1] + [2] = 0, + }; +} -- GitLab From 92631a4824a91f3268a5716dd3459df8dc6bfb63 Mon Sep 17 00:00:00 2001 From: Miro Bucko Date: Mon, 22 Apr 2024 13:40:06 -0400 Subject: [PATCH 012/732] [lldb][MinidumpFileBuilder] Fix addition of MemoryList steam (#88564) Summary: AddMemoryList() was returning the last error status returned by ReadMemory(). So if an invalid memory region was read last, the function would return an error. Test Plan: ./bin/llvm-lit -sv ~/src/llvm-project/lldb/test/API/functionalities/process_save_core_minidump/TestProcessSaveCoreMinidump.py Reviewers: kevinfrei,clayborg Subscribers: Tasks: Tags: --- .../ObjectFile/Minidump/MinidumpFileBuilder.cpp | 11 +++++++++-- lldb/source/Target/Process.cpp | 7 +++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp b/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp index cefd4cb22b6b..601f11d51d42 100644 --- a/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp +++ b/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp @@ -21,6 +21,7 @@ #include "lldb/Target/ThreadList.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/LLDBLog.h" +#include "lldb/Utility/Log.h" #include "lldb/Utility/RegisterValue.h" #include "llvm/ADT/StringRef.h" @@ -663,14 +664,20 @@ MinidumpFileBuilder::AddMemoryList(const lldb::ProcessSP &process_sp, DataBufferHeap helper_data; std::vector mem_descriptors; for (const auto &core_range : core_ranges) { - // Skip empty memory regions or any regions with no permissions. - if (core_range.range.empty() || core_range.lldb_permissions == 0) + // Skip empty memory regions. + if (core_range.range.empty()) continue; const addr_t addr = core_range.range.start(); const addr_t size = core_range.range.size(); auto data_up = std::make_unique(size, 0); const size_t bytes_read = process_sp->ReadMemory(addr, data_up->GetBytes(), size, error); + if (error.Fail()) { + Log *log = GetLog(LLDBLog::Object); + LLDB_LOGF(log, "Failed to read memory region. Bytes read: %zu, error: %s", + bytes_read, error.AsCString()); + error.Clear(); + } if (bytes_read == 0) continue; // We have a good memory region with valid bytes to store. diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index f02ec37cb0f0..606518ca5412 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -6325,8 +6325,11 @@ static bool AddDirtyPages(const MemoryRegionInfo ®ion, // ranges. static void AddRegion(const MemoryRegionInfo ®ion, bool try_dirty_pages, Process::CoreFileMemoryRanges &ranges) { - // Don't add empty ranges or ranges with no permissions. - if (region.GetRange().GetByteSize() == 0 || region.GetLLDBPermissions() == 0) + // Don't add empty ranges. + if (region.GetRange().GetByteSize() == 0) + return; + // Don't add ranges with no read permissions. + if ((region.GetLLDBPermissions() & lldb::ePermissionsReadable) == 0) return; if (try_dirty_pages && AddDirtyPages(region, ranges)) return; -- GitLab From f352ce368af39e57d337495d7ca3a21975ede8e6 Mon Sep 17 00:00:00 2001 From: Michal Paszkowski Date: Mon, 22 Apr 2024 10:47:46 -0700 Subject: [PATCH 013/732] [SPIR-V] Emit SPIR-V generator magic number and version (#87951) This patch: - Adds SPIR-V backend's registered generator magic number to the emitted binary. The magic number consists of the generator ID (43) and LLVM major version. - Adds SPIR-V version to the binary. - Allows reading the expected (maximum supported) SPIR-V version from the target triple. - Uses VersionTuple for representing versions throughout the backend's codebase. - Registers v1.6 for spirv32 and spirv64 triple. See more: https://github.com/KhronosGroup/SPIRV-Headers/commit/7d500c --- llvm/lib/MC/SPIRVObjectWriter.cpp | 6 +-- .../SPIRV/MCTargetDesc/SPIRVBaseInfo.cpp | 12 ++--- .../Target/SPIRV/MCTargetDesc/SPIRVBaseInfo.h | 5 +- llvm/lib/Target/SPIRV/SPIRV.td | 13 ----- llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp | 10 ++-- llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp | 52 +++++++++++-------- llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h | 20 ++++--- llvm/lib/Target/SPIRV/SPIRVSubtarget.cpp | 43 +++++++++++---- llvm/lib/Target/SPIRV/SPIRVSubtarget.h | 10 ++-- llvm/lib/TargetParser/Triple.cpp | 6 ++- llvm/test/CodeGen/SPIRV/ComparePointers.ll | 4 +- llvm/test/CodeGen/SPIRV/empty-opencl32.ll | 2 - .../SPIRV/exec_mode_float_control_khr.ll | 4 +- .../physical-layout/generator-magic-number.ll | 4 ++ .../SPIRV/physical-layout/spirv-version.ll | 16 ++++++ .../AtomicCompareExchangeExplicit_cl20.ll | 4 +- 16 files changed, 123 insertions(+), 88 deletions(-) create mode 100644 llvm/test/CodeGen/SPIRV/physical-layout/generator-magic-number.ll create mode 100644 llvm/test/CodeGen/SPIRV/physical-layout/spirv-version.ll diff --git a/llvm/lib/MC/SPIRVObjectWriter.cpp b/llvm/lib/MC/SPIRVObjectWriter.cpp index d72d6e07f2e6..5d85c5de4e4e 100644 --- a/llvm/lib/MC/SPIRVObjectWriter.cpp +++ b/llvm/lib/MC/SPIRVObjectWriter.cpp @@ -43,10 +43,10 @@ private: void SPIRVObjectWriter::writeHeader(const MCAssembler &Asm) { constexpr uint32_t MagicNumber = 0x07230203; - constexpr uint32_t GeneratorMagicNumber = 0; + constexpr uint32_t GeneratorID = 43; + constexpr uint32_t GeneratorMagicNumber = + (GeneratorID << 16) | (LLVM_VERSION_MAJOR); constexpr uint32_t Schema = 0; - - // Construct SPIR-V version and Bound const MCAssembler::VersionInfoType &VIT = Asm.getVersionInfo(); uint32_t VersionNumber = 0 | (VIT.Major << 16) | (VIT.Minor << 8); uint32_t Bound = VIT.Update; diff --git a/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVBaseInfo.cpp b/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVBaseInfo.cpp index b69031adb167..d96d2bf31b62 100644 --- a/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVBaseInfo.cpp +++ b/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVBaseInfo.cpp @@ -88,28 +88,28 @@ getSymbolicOperandMnemonic(SPIRV::OperandCategory::OperandCategory Category, return Name; } -uint32_t +VersionTuple getSymbolicOperandMinVersion(SPIRV::OperandCategory::OperandCategory Category, uint32_t Value) { const SPIRV::SymbolicOperand *Lookup = SPIRV::lookupSymbolicOperandByCategoryAndValue(Category, Value); if (Lookup) - return Lookup->MinVersion; + return VersionTuple(Lookup->MinVersion / 10, Lookup->MinVersion % 10); - return 0; + return VersionTuple(0); } -uint32_t +VersionTuple getSymbolicOperandMaxVersion(SPIRV::OperandCategory::OperandCategory Category, uint32_t Value) { const SPIRV::SymbolicOperand *Lookup = SPIRV::lookupSymbolicOperandByCategoryAndValue(Category, Value); if (Lookup) - return Lookup->MaxVersion; + return VersionTuple(Lookup->MaxVersion / 10, Lookup->MaxVersion % 10); - return 0; + return VersionTuple(); } CapabilityList diff --git a/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVBaseInfo.h b/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVBaseInfo.h index 616d2ea71b39..990eb1d230bc 100644 --- a/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVBaseInfo.h +++ b/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVBaseInfo.h @@ -17,6 +17,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/VersionTuple.h" #include namespace llvm { @@ -214,10 +215,10 @@ using ExtensionList = SmallVector; std::string getSymbolicOperandMnemonic(SPIRV::OperandCategory::OperandCategory Category, int32_t Value); -uint32_t +VersionTuple getSymbolicOperandMinVersion(SPIRV::OperandCategory::OperandCategory Category, uint32_t Value); -uint32_t +VersionTuple getSymbolicOperandMaxVersion(SPIRV::OperandCategory::OperandCategory Category, uint32_t Value); CapabilityList diff --git a/llvm/lib/Target/SPIRV/SPIRV.td b/llvm/lib/Target/SPIRV/SPIRV.td index beb55d05307c..108c7e6d3861 100644 --- a/llvm/lib/Target/SPIRV/SPIRV.td +++ b/llvm/lib/Target/SPIRV/SPIRV.td @@ -20,19 +20,6 @@ class Proc Features> def : Proc<"generic", []>; -def SPIRV10 : SubtargetFeature<"spirv1.0", "SPIRVVersion", "10", - "Use SPIR-V version 1.0">; -def SPIRV11 : SubtargetFeature<"spirv1.1", "SPIRVVersion", "11", - "Use SPIR-V version 1.1">; -def SPIRV12 : SubtargetFeature<"spirv1.2", "SPIRVVersion", "12", - "Use SPIR-V version 1.2">; -def SPIRV13 : SubtargetFeature<"spirv1.3", "SPIRVVersion", "13", - "Use SPIR-V version 1.3">; -def SPIRV14 : SubtargetFeature<"spirv1.4", "SPIRVVersion", "14", - "Use SPIR-V version 1.4">; -def SPIRV15 : SubtargetFeature<"spirv1.5", "SPIRVVersion", "15", - "Use SPIR-V version 1.5">; - def SPIRVInstPrinter : AsmWriter { string AsmWriterClassName = "InstPrinter"; bit isMCAsmWriter = 1; diff --git a/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp b/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp index 1de4616fd5b7..2ebe5bdc4771 100644 --- a/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp @@ -108,9 +108,9 @@ void SPIRVAsmPrinter::emitEndOfAsmFile(Module &M) { } ST = static_cast(TM).getSubtargetImpl(); - uint32_t DecSPIRVVersion = ST->getSPIRVVersion(); - uint32_t Major = DecSPIRVVersion / 10; - uint32_t Minor = DecSPIRVVersion - Major * 10; + VersionTuple SPIRVVersion = ST->getSPIRVVersion(); + uint32_t Major = SPIRVVersion.getMajor(); + uint32_t Minor = SPIRVVersion.getMinor().value_or(0); // Bound is an approximation that accounts for the maximum used register // number and number of generated OpLabels unsigned Bound = 2 * (ST->getBound() + 1) + NLabels; @@ -321,8 +321,8 @@ void SPIRVAsmPrinter::outputEntryPoints() { // the Input and Output storage classes. Starting with version 1.4, // the interface's storage classes are all storage classes used in // declaring all global variables referenced by the entry point call tree. - if (ST->getSPIRVVersion() >= 14 || SC == SPIRV::StorageClass::Input || - SC == SPIRV::StorageClass::Output) { + if (ST->isAtLeastSPIRVVer(VersionTuple(1, 4)) || + SC == SPIRV::StorageClass::Input || SC == SPIRV::StorageClass::Output) { MachineFunction *MF = MI->getMF(); Register Reg = MAI->getRegisterAlias(MF, MI->getOperand(0).getReg()); InterfaceIDs.insert(Reg); diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp index 8395d4b2bf66..235f947901d8 100644 --- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp @@ -76,18 +76,20 @@ getSymbolicOperandRequirements(SPIRV::OperandCategory::OperandCategory Category, SPIRV::RequirementHandler &Reqs) { static AvoidCapabilitiesSet AvoidCaps; // contains capabilities to avoid if there is another option - unsigned ReqMinVer = getSymbolicOperandMinVersion(Category, i); - unsigned ReqMaxVer = getSymbolicOperandMaxVersion(Category, i); - unsigned TargetVer = ST.getSPIRVVersion(); - bool MinVerOK = !ReqMinVer || !TargetVer || TargetVer >= ReqMinVer; - bool MaxVerOK = !ReqMaxVer || !TargetVer || TargetVer <= ReqMaxVer; + + VersionTuple ReqMinVer = getSymbolicOperandMinVersion(Category, i); + VersionTuple ReqMaxVer = getSymbolicOperandMaxVersion(Category, i); + VersionTuple SPIRVVersion = ST.getSPIRVVersion(); + bool MinVerOK = SPIRVVersion.empty() || SPIRVVersion >= ReqMinVer; + bool MaxVerOK = + ReqMaxVer.empty() || SPIRVVersion.empty() || SPIRVVersion <= ReqMaxVer; CapabilityList ReqCaps = getSymbolicOperandCapabilities(Category, i); ExtensionList ReqExts = getSymbolicOperandExtensions(Category, i); if (ReqCaps.empty()) { if (ReqExts.empty()) { if (MinVerOK && MaxVerOK) return {true, {}, {}, ReqMinVer, ReqMaxVer}; - return {false, {}, {}, 0, 0}; + return {false, {}, {}, VersionTuple(), VersionTuple()}; } } else if (MinVerOK && MaxVerOK) { if (ReqCaps.size() == 1) { @@ -118,9 +120,13 @@ getSymbolicOperandRequirements(SPIRV::OperandCategory::OperandCategory Category, if (llvm::all_of(ReqExts, [&ST](const SPIRV::Extension::Extension &Ext) { return ST.canUseExtension(Ext); })) { - return {true, {}, ReqExts, 0, 0}; // TODO: add versions to extensions. + return {true, + {}, + ReqExts, + VersionTuple(), + VersionTuple()}; // TODO: add versions to extensions. } - return {false, {}, {}, 0, 0}; + return {false, {}, {}, VersionTuple(), VersionTuple()}; } void SPIRVModuleAnalysis::setBaseInfo(const Module &M) { @@ -510,25 +516,25 @@ void SPIRV::RequirementHandler::addRequirements( addExtensions(Req.Exts); - if (Req.MinVer) { - if (MaxVersion && Req.MinVer > MaxVersion) { + if (!Req.MinVer.empty()) { + if (!MaxVersion.empty() && Req.MinVer > MaxVersion) { LLVM_DEBUG(dbgs() << "Conflicting version requirements: >= " << Req.MinVer << " and <= " << MaxVersion << "\n"); report_fatal_error("Adding SPIR-V requirements that can't be satisfied."); } - if (MinVersion == 0 || Req.MinVer > MinVersion) + if (MinVersion.empty() || Req.MinVer > MinVersion) MinVersion = Req.MinVer; } - if (Req.MaxVer) { - if (MinVersion && Req.MaxVer < MinVersion) { + if (!Req.MaxVer.empty()) { + if (!MinVersion.empty() && Req.MaxVer < MinVersion) { LLVM_DEBUG(dbgs() << "Conflicting version requirements: <= " << Req.MaxVer << " and >= " << MinVersion << "\n"); report_fatal_error("Adding SPIR-V requirements that can't be satisfied."); } - if (MaxVersion == 0 || Req.MaxVer < MaxVersion) + if (MaxVersion.empty() || Req.MaxVer < MaxVersion) MaxVersion = Req.MaxVer; } } @@ -539,7 +545,7 @@ void SPIRV::RequirementHandler::checkSatisfiable( bool IsSatisfiable = true; auto TargetVer = ST.getSPIRVVersion(); - if (MaxVersion && TargetVer && MaxVersion < TargetVer) { + if (!MaxVersion.empty() && !TargetVer.empty() && MaxVersion < TargetVer) { LLVM_DEBUG( dbgs() << "Target SPIR-V version too high for required features\n" << "Required max version: " << MaxVersion << " target version " @@ -547,14 +553,14 @@ void SPIRV::RequirementHandler::checkSatisfiable( IsSatisfiable = false; } - if (MinVersion && TargetVer && MinVersion > TargetVer) { + if (!MinVersion.empty() && !TargetVer.empty() && MinVersion > TargetVer) { LLVM_DEBUG(dbgs() << "Target SPIR-V version too low for required features\n" << "Required min version: " << MinVersion << " target version " << TargetVer << "\n"); IsSatisfiable = false; } - if (MinVersion && MaxVersion && MinVersion > MaxVersion) { + if (!MinVersion.empty() && !MaxVersion.empty() && MinVersion > MaxVersion) { LLVM_DEBUG( dbgs() << "Version is too low for some features and too high for others.\n" @@ -632,12 +638,13 @@ void RequirementHandler::initAvailableCapabilitiesForOpenCL( addAvailableCaps({Capability::ImageBasic, Capability::LiteralSampler, Capability::Image1D, Capability::SampledBuffer, Capability::ImageBuffer}); - if (ST.isAtLeastOpenCLVer(20)) + if (ST.isAtLeastOpenCLVer(VersionTuple(2, 0))) addAvailableCaps({Capability::ImageReadWrite}); } - if (ST.isAtLeastSPIRVVer(11) && ST.isAtLeastOpenCLVer(22)) + if (ST.isAtLeastSPIRVVer(VersionTuple(1, 1)) && + ST.isAtLeastOpenCLVer(VersionTuple(2, 2))) addAvailableCaps({Capability::SubgroupDispatch, Capability::PipeStorage}); - if (ST.isAtLeastSPIRVVer(13)) + if (ST.isAtLeastSPIRVVer(VersionTuple(1, 3))) addAvailableCaps({Capability::GroupNonUniform, Capability::GroupNonUniformVote, Capability::GroupNonUniformArithmetic, @@ -645,7 +652,7 @@ void RequirementHandler::initAvailableCapabilitiesForOpenCL( Capability::GroupNonUniformClustered, Capability::GroupNonUniformShuffle, Capability::GroupNonUniformShuffleRelative}); - if (ST.isAtLeastSPIRVVer(14)) + if (ST.isAtLeastSPIRVVer(VersionTuple(1, 4))) addAvailableCaps({Capability::DenormPreserve, Capability::DenormFlushToZero, Capability::SignedZeroInfNanPreserve, Capability::RoundingModeRTE, @@ -1162,7 +1169,8 @@ static void collectReqs(const Module &M, SPIRV::ModuleAnalysisInfo &MAI, auto Node = M.getNamedMetadata("spirv.ExecutionMode"); if (Node) { // SPV_KHR_float_controls is not available until v1.4 - bool RequireFloatControls = false, VerLower14 = !ST.isAtLeastSPIRVVer(14); + bool RequireFloatControls = false, + VerLower14 = !ST.isAtLeastSPIRVVer(VersionTuple(1, 4)); for (unsigned i = 0; i < Node->getNumOperands(); i++) { MDNode *MDN = cast(Node->getOperand(i)); const MDOperand &MDOp = MDN->getOperand(1); diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h index 6e86eed30c5d..79226d6d93ef 100644 --- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h +++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h @@ -45,13 +45,13 @@ struct Requirements { const bool IsSatisfiable; const std::optional Cap; const ExtensionList Exts; - const unsigned MinVer; // 0 if no min version is required. - const unsigned MaxVer; // 0 if no max version is required. + const VersionTuple MinVer; // 0 if no min version is required. + const VersionTuple MaxVer; // 0 if no max version is required. Requirements(bool IsSatisfiable = false, std::optional Cap = {}, - ExtensionList Exts = {}, unsigned MinVer = 0, - unsigned MaxVer = 0) + ExtensionList Exts = {}, VersionTuple MinVer = VersionTuple(), + VersionTuple MaxVer = VersionTuple()) : IsSatisfiable(IsSatisfiable), Cap(Cap), Exts(Exts), MinVer(MinVer), MaxVer(MaxVer) {} Requirements(Capability::Capability Cap) : Requirements(true, {Cap}) {} @@ -69,8 +69,8 @@ private: DenseSet AvailableCaps; SmallSet AllExtensions; - unsigned MinVersion; // 0 if no min version is defined. - unsigned MaxVersion; // 0 if no max version is defined. + VersionTuple MinVersion; // 0 if no min version is defined. + VersionTuple MaxVersion; // 0 if no max version is defined. // Add capabilities to AllCaps, recursing through their implicitly declared // capabilities too. void recursiveAddCapabilities(const CapabilityList &ToPrune); @@ -79,17 +79,15 @@ private: void initAvailableCapabilitiesForVulkan(const SPIRVSubtarget &ST); public: - RequirementHandler() : MinVersion(0), MaxVersion(0) {} + RequirementHandler() {} void clear() { MinimalCaps.clear(); AllCaps.clear(); AvailableCaps.clear(); AllExtensions.clear(); - MinVersion = 0; - MaxVersion = 0; + MinVersion = VersionTuple(); + MaxVersion = VersionTuple(); } - unsigned getMinVersion() const { return MinVersion; } - unsigned getMaxVersion() const { return MaxVersion; } const CapabilityList &getMinimalCapabilities() const { return MinimalCaps; } const SmallSet &getExtensions() const { return AllExtensions; diff --git a/llvm/lib/Target/SPIRV/SPIRVSubtarget.cpp b/llvm/lib/Target/SPIRV/SPIRVSubtarget.cpp index f3864b56e1e9..7aa0c566c75f 100644 --- a/llvm/lib/Target/SPIRV/SPIRVSubtarget.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVSubtarget.cpp @@ -39,18 +39,43 @@ static cl::opt, false, cl::desc("Specify list of enabled SPIR-V extensions")); // Compare version numbers, but allow 0 to mean unspecified. -static bool isAtLeastVer(uint32_t Target, uint32_t VerToCompareTo) { - return Target == 0 || Target >= VerToCompareTo; +static bool isAtLeastVer(VersionTuple Target, VersionTuple VerToCompareTo) { + return Target.empty() || Target >= VerToCompareTo; } SPIRVSubtarget::SPIRVSubtarget(const Triple &TT, const std::string &CPU, const std::string &FS, const SPIRVTargetMachine &TM) : SPIRVGenSubtargetInfo(TT, CPU, /*TuneCPU=*/CPU, FS), - PointerSize(TM.getPointerSizeInBits(/* AS= */ 0)), SPIRVVersion(0), - OpenCLVersion(0), InstrInfo(), + PointerSize(TM.getPointerSizeInBits(/* AS= */ 0)), InstrInfo(), FrameLowering(initSubtargetDependencies(CPU, FS)), TLInfo(TM, *this), TargetTriple(TT) { + switch (TT.getSubArch()) { + case Triple::SPIRVSubArch_v10: + SPIRVVersion = VersionTuple(1, 0); + break; + case Triple::SPIRVSubArch_v11: + SPIRVVersion = VersionTuple(1, 1); + break; + case Triple::SPIRVSubArch_v12: + SPIRVVersion = VersionTuple(1, 2); + break; + case Triple::SPIRVSubArch_v13: + SPIRVVersion = VersionTuple(1, 3); + break; + case Triple::SPIRVSubArch_v14: + default: + SPIRVVersion = VersionTuple(1, 4); + break; + case Triple::SPIRVSubArch_v15: + SPIRVVersion = VersionTuple(1, 5); + break; + case Triple::SPIRVSubArch_v16: + SPIRVVersion = VersionTuple(1, 6); + break; + } + OpenCLVersion = VersionTuple(2, 2); + // The order of initialization is important. initAvailableExtensions(); initAvailableExtInstSets(); @@ -66,10 +91,6 @@ SPIRVSubtarget::SPIRVSubtarget(const Triple &TT, const std::string &CPU, SPIRVSubtarget &SPIRVSubtarget::initSubtargetDependencies(StringRef CPU, StringRef FS) { ParseSubtargetFeatures(CPU, /*TuneCPU=*/CPU, FS); - if (SPIRVVersion == 0) - SPIRVVersion = 14; - if (OpenCLVersion == 0) - OpenCLVersion = 22; return *this; } @@ -82,11 +103,11 @@ bool SPIRVSubtarget::canUseExtInstSet( return AvailableExtInstSets.contains(E); } -bool SPIRVSubtarget::isAtLeastSPIRVVer(uint32_t VerToCompareTo) const { +bool SPIRVSubtarget::isAtLeastSPIRVVer(VersionTuple VerToCompareTo) const { return isAtLeastVer(SPIRVVersion, VerToCompareTo); } -bool SPIRVSubtarget::isAtLeastOpenCLVer(uint32_t VerToCompareTo) const { +bool SPIRVSubtarget::isAtLeastOpenCLVer(VersionTuple VerToCompareTo) const { if (!isOpenCLEnv()) return false; return isAtLeastVer(OpenCLVersion, VerToCompareTo); @@ -95,7 +116,7 @@ bool SPIRVSubtarget::isAtLeastOpenCLVer(uint32_t VerToCompareTo) const { // If the SPIR-V version is >= 1.4 we can call OpPtrEqual and OpPtrNotEqual. // In SPIR-V Translator compatibility mode this feature is not available. bool SPIRVSubtarget::canDirectlyComparePointers() const { - return !SPVTranslatorCompat && isAtLeastVer(SPIRVVersion, 14); + return !SPVTranslatorCompat && isAtLeastVer(SPIRVVersion, VersionTuple(1, 4)); } void SPIRVSubtarget::initAvailableExtensions() { diff --git a/llvm/lib/Target/SPIRV/SPIRVSubtarget.h b/llvm/lib/Target/SPIRV/SPIRVSubtarget.h index 3b486226a939..3e4044084266 100644 --- a/llvm/lib/Target/SPIRV/SPIRVSubtarget.h +++ b/llvm/lib/Target/SPIRV/SPIRVSubtarget.h @@ -37,8 +37,8 @@ class SPIRVTargetMachine; class SPIRVSubtarget : public SPIRVGenSubtargetInfo { private: const unsigned PointerSize; - uint32_t SPIRVVersion; - uint32_t OpenCLVersion; + VersionTuple SPIRVVersion; + VersionTuple OpenCLVersion; SmallSet AvailableExtensions; SmallSet AvailableExtInstSets; @@ -81,9 +81,9 @@ public: TargetTriple.getArch() == Triple::spirv64; } bool isVulkanEnv() const { return TargetTriple.getArch() == Triple::spirv; } - uint32_t getSPIRVVersion() const { return SPIRVVersion; }; - bool isAtLeastSPIRVVer(uint32_t VerToCompareTo) const; - bool isAtLeastOpenCLVer(uint32_t VerToCompareTo) const; + VersionTuple getSPIRVVersion() const { return SPIRVVersion; }; + bool isAtLeastSPIRVVer(VersionTuple VerToCompareTo) const; + bool isAtLeastOpenCLVer(VersionTuple VerToCompareTo) const; // TODO: implement command line args or other ways to determine this. bool hasOpenCLFullProfile() const { return true; } bool hasOpenCLImageSupport() const { return true; } diff --git a/llvm/lib/TargetParser/Triple.cpp b/llvm/lib/TargetParser/Triple.cpp index 77fdf31d4865..2c5aee3dfb2f 100644 --- a/llvm/lib/TargetParser/Triple.cpp +++ b/llvm/lib/TargetParser/Triple.cpp @@ -559,9 +559,11 @@ static Triple::ArchType parseArch(StringRef ArchName) { .Case("spir64", Triple::spir64) .Cases("spirv", "spirv1.5", "spirv1.6", Triple::spirv) .Cases("spirv32", "spirv32v1.0", "spirv32v1.1", "spirv32v1.2", - "spirv32v1.3", "spirv32v1.4", "spirv32v1.5", Triple::spirv32) + "spirv32v1.3", "spirv32v1.4", "spirv32v1.5", + "spirv32v1.6", Triple::spirv32) .Cases("spirv64", "spirv64v1.0", "spirv64v1.1", "spirv64v1.2", - "spirv64v1.3", "spirv64v1.4", "spirv64v1.5", Triple::spirv64) + "spirv64v1.3", "spirv64v1.4", "spirv64v1.5", + "spirv64v1.6", Triple::spirv64) .StartsWith("kalimba", Triple::kalimba) .Case("lanai", Triple::lanai) .Case("renderscript32", Triple::renderscript32) diff --git a/llvm/test/CodeGen/SPIRV/ComparePointers.ll b/llvm/test/CodeGen/SPIRV/ComparePointers.ll index 6777fc38024b..408b95579502 100644 --- a/llvm/test/CodeGen/SPIRV/ComparePointers.ll +++ b/llvm/test/CodeGen/SPIRV/ComparePointers.ll @@ -1,5 +1,5 @@ -; RUN: llc -O0 -mtriple=spirv64-unknown-unknown --mattr=+spirv1.3 %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV -; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %} +; RUN: llc -O0 -mtriple=spirv64v1.3-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV +; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64v1.3-unknown-unknown %s -o - -filetype=obj | spirv-val %} ;; kernel void test(int global *in, int global *in2) { ;; if (!in) diff --git a/llvm/test/CodeGen/SPIRV/empty-opencl32.ll b/llvm/test/CodeGen/SPIRV/empty-opencl32.ll index 8e826ec35f37..5b007c7e8adc 100644 --- a/llvm/test/CodeGen/SPIRV/empty-opencl32.ll +++ b/llvm/test/CodeGen/SPIRV/empty-opencl32.ll @@ -1,8 +1,6 @@ ; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s ; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %} -;; FIXME: ensure Magic Number, version number, generator's magic number, "bound" and "schema" are at least present - ;; Ensure the required Capabilities are listed. ; CHECK-DAG: OpCapability Kernel ; CHECK-DAG: OpCapability Addresses diff --git a/llvm/test/CodeGen/SPIRV/exec_mode_float_control_khr.ll b/llvm/test/CodeGen/SPIRV/exec_mode_float_control_khr.ll index 721e825a1c98..d3131e560685 100644 --- a/llvm/test/CodeGen/SPIRV/exec_mode_float_control_khr.ll +++ b/llvm/test/CodeGen/SPIRV/exec_mode_float_control_khr.ll @@ -1,5 +1,5 @@ -; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s --check-prefixes=SPV -; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s --mattr=+spirv1.3 --spirv-ext=+SPV_KHR_float_controls -o - | FileCheck %s --check-prefixes=SPVEXT +; RUN: llc -O0 -mtriple=spirv32v1.3-unknown-unknown %s -o - | FileCheck %s --check-prefixes=SPV +; RUN: llc -O0 -mtriple=spirv32v1.3-unknown-unknown %s --spirv-ext=+SPV_KHR_float_controls -o - | FileCheck %s --check-prefixes=SPVEXT define dso_local dllexport spir_kernel void @k_float_controls_0(i32 %ibuf, i32 %obuf) local_unnamed_addr { entry: diff --git a/llvm/test/CodeGen/SPIRV/physical-layout/generator-magic-number.ll b/llvm/test/CodeGen/SPIRV/physical-layout/generator-magic-number.ll new file mode 100644 index 000000000000..afffd9e69b45 --- /dev/null +++ b/llvm/test/CodeGen/SPIRV/physical-layout/generator-magic-number.ll @@ -0,0 +1,4 @@ +; REQUIRES: spirv-tools +; RUN: llc -O0 -mtriple=spirv-unknown-unknown %s -o - --filetype=obj | spirv-dis | FileCheck %s + +; CHECK: Generator: {{.*}}{{43|LLVM SPIR-V Backend}}{{.*}} diff --git a/llvm/test/CodeGen/SPIRV/physical-layout/spirv-version.ll b/llvm/test/CodeGen/SPIRV/physical-layout/spirv-version.ll new file mode 100644 index 000000000000..686c1e97257a --- /dev/null +++ b/llvm/test/CodeGen/SPIRV/physical-layout/spirv-version.ll @@ -0,0 +1,16 @@ +; REQUIRES: spirv-tools +; RUN: llc -O0 -mtriple=spirv64v1.0-unknown-unknown %s -o - --filetype=obj | spirv-dis | FileCheck %s --check-prefix=CHECK-SPIRV10 +; RUN: llc -O0 -mtriple=spirv64v1.1-unknown-unknown %s -o - --filetype=obj | spirv-dis | FileCheck %s --check-prefix=CHECK-SPIRV11 +; RUN: llc -O0 -mtriple=spirv64v1.2-unknown-unknown %s -o - --filetype=obj | spirv-dis | FileCheck %s --check-prefix=CHECK-SPIRV12 +; RUN: llc -O0 -mtriple=spirv64v1.3-unknown-unknown %s -o - --filetype=obj | spirv-dis | FileCheck %s --check-prefix=CHECK-SPIRV13 +; RUN: llc -O0 -mtriple=spirv64v1.4-unknown-unknown %s -o - --filetype=obj | spirv-dis | FileCheck %s --check-prefix=CHECK-SPIRV14 +; RUN: llc -O0 -mtriple=spirv64v1.5-unknown-unknown %s -o - --filetype=obj | spirv-dis | FileCheck %s --check-prefix=CHECK-SPIRV15 +; RUN: llc -O0 -mtriple=spirv64v1.6-unknown-unknown %s -o - --filetype=obj | spirv-dis | FileCheck %s --check-prefix=CHECK-SPIRV16 + +; CHECK-SPIRV10: Version: 1.0 +; CHECK-SPIRV11: Version: 1.1 +; CHECK-SPIRV12: Version: 1.2 +; CHECK-SPIRV13: Version: 1.3 +; CHECK-SPIRV14: Version: 1.4 +; CHECK-SPIRV15: Version: 1.5 +; CHECK-SPIRV16: Version: 1.6 diff --git a/llvm/test/CodeGen/SPIRV/transcoding/AtomicCompareExchangeExplicit_cl20.ll b/llvm/test/CodeGen/SPIRV/transcoding/AtomicCompareExchangeExplicit_cl20.ll index e0c47798cc6d..cb5bce1375b6 100644 --- a/llvm/test/CodeGen/SPIRV/transcoding/AtomicCompareExchangeExplicit_cl20.ll +++ b/llvm/test/CodeGen/SPIRV/transcoding/AtomicCompareExchangeExplicit_cl20.ll @@ -1,5 +1,5 @@ -; RUN: llc -O0 -mtriple=spirv32-unknown-unknown --mattr=+spirv1.3 %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV -; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown --mattr=+spirv1.3 %s -o - -filetype=obj | spirv-val %} +; RUN: llc -O0 -mtriple=spirv32v1.3-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV +; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32v1.3-unknown-unknown %s -o - -filetype=obj | spirv-val %} ;; __kernel void testAtomicCompareExchangeExplicit_cl20( ;; volatile global atomic_int* object, -- GitLab From 9c9dea943706340f8a45dc74887bf9beddd67810 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Mon, 22 Apr 2024 13:04:20 -0500 Subject: [PATCH 014/732] [flang][OpenMP] Concatenate begin and end clauses into single list (#89090) This will remove the distinction between begin clauses and end clauses, and process all of them together. --- flang/lib/Lower/OpenMP/OpenMP.cpp | 253 +++++++++++++----------------- 1 file changed, 110 insertions(+), 143 deletions(-) diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp index db99617a7ba9..e932f7c284bc 100644 --- a/flang/lib/Lower/OpenMP/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP/OpenMP.cpp @@ -1089,16 +1089,12 @@ static void genParallelClauses( static void genSectionsClauses(Fortran::lower::AbstractConverter &converter, Fortran::semantics::SemanticsContext &semaCtx, const List &clauses, mlir::Location loc, - bool clausesFromBeginSections, mlir::omp::SectionsClauseOps &clauseOps) { ClauseProcessor cp(converter, semaCtx, clauses); - if (clausesFromBeginSections) { - cp.processAllocate(clauseOps); - cp.processSectionsReduction(loc, clauseOps); - // TODO Support delayed privatization. - } else { - cp.processNowait(clauseOps); - } + cp.processAllocate(clauseOps); + cp.processSectionsReduction(loc, clauseOps); + cp.processNowait(clauseOps); + // TODO Support delayed privatization. } static void genSimdClauses(Fortran::lower::AbstractConverter &converter, @@ -1119,16 +1115,13 @@ static void genSimdClauses(Fortran::lower::AbstractConverter &converter, static void genSingleClauses(Fortran::lower::AbstractConverter &converter, Fortran::semantics::SemanticsContext &semaCtx, - const List &beginClauses, - const List &endClauses, mlir::Location loc, + const List &clauses, mlir::Location loc, mlir::omp::SingleClauseOps &clauseOps) { - ClauseProcessor bcp(converter, semaCtx, beginClauses); - bcp.processAllocate(clauseOps); + ClauseProcessor cp(converter, semaCtx, clauses); + cp.processAllocate(clauseOps); + cp.processCopyprivate(loc, clauseOps); + cp.processNowait(clauseOps); // TODO Support delayed privatization. - - ClauseProcessor ecp(converter, semaCtx, endClauses); - ecp.processCopyprivate(loc, clauseOps); - ecp.processNowait(clauseOps); } static void genTargetClauses( @@ -1278,30 +1271,25 @@ static void genWsloopClauses( Fortran::lower::AbstractConverter &converter, Fortran::semantics::SemanticsContext &semaCtx, Fortran::lower::StatementContext &stmtCtx, - Fortran::lower::pft::Evaluation &eval, const List &beginClauses, - const List &endClauses, mlir::Location loc, - mlir::omp::WsloopClauseOps &clauseOps, + Fortran::lower::pft::Evaluation &eval, const List &clauses, + mlir::Location loc, mlir::omp::WsloopClauseOps &clauseOps, llvm::SmallVectorImpl &iv, llvm::SmallVectorImpl &reductionTypes, llvm::SmallVectorImpl &reductionSyms) { fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); - ClauseProcessor bcp(converter, semaCtx, beginClauses); - bcp.processCollapse(loc, eval, clauseOps, iv); - bcp.processOrdered(clauseOps); - bcp.processReduction(loc, clauseOps, &reductionTypes, &reductionSyms); - bcp.processSchedule(stmtCtx, clauseOps); + ClauseProcessor cp(converter, semaCtx, clauses); + cp.processCollapse(loc, eval, clauseOps, iv); + cp.processNowait(clauseOps); + cp.processOrdered(clauseOps); + cp.processReduction(loc, clauseOps, &reductionTypes, &reductionSyms); + cp.processSchedule(stmtCtx, clauseOps); clauseOps.loopInclusiveAttr = firOpBuilder.getUnitAttr(); // TODO Support delayed privatization. if (ReductionProcessor::doReductionByRef(clauseOps.reductionVars)) clauseOps.reductionByRefAttr = firOpBuilder.getUnitAttr(); - if (!endClauses.empty()) { - ClauseProcessor ecp(converter, semaCtx, endClauses); - ecp.processNowait(clauseOps); - } - - bcp.processTODO( + cp.processTODO( loc, llvm::omp::Directive::OMPD_do); } @@ -1555,17 +1543,15 @@ static mlir::omp::SingleOp genSingleOp(Fortran::lower::AbstractConverter &converter, Fortran::semantics::SemanticsContext &semaCtx, Fortran::lower::pft::Evaluation &eval, bool genNested, - mlir::Location loc, const List &beginClauses, - const List &endClauses) { + mlir::Location loc, const List &clauses) { mlir::omp::SingleClauseOps clauseOps; - genSingleClauses(converter, semaCtx, beginClauses, endClauses, loc, - clauseOps); + genSingleClauses(converter, semaCtx, clauses, loc, clauseOps); return genOpWithBody( OpWithBodyGenInfo(converter, semaCtx, loc, eval, llvm::omp::Directive::OMPD_single) .setGenNested(genNested) - .setClauses(&beginClauses), + .setClauses(&clauses), clauseOps); } @@ -1814,8 +1800,8 @@ static mlir::omp::WsloopOp genWsloopOp(Fortran::lower::AbstractConverter &converter, Fortran::semantics::SemanticsContext &semaCtx, Fortran::lower::pft::Evaluation &eval, mlir::Location loc, - const List &beginClauses, const List &endClauses) { - DataSharingProcessor dsp(converter, semaCtx, beginClauses, eval); + const List &clauses) { + DataSharingProcessor dsp(converter, semaCtx, clauses, eval); dsp.processStep1(); Fortran::lower::StatementContext stmtCtx; @@ -1823,10 +1809,10 @@ genWsloopOp(Fortran::lower::AbstractConverter &converter, llvm::SmallVector iv; llvm::SmallVector reductionTypes; llvm::SmallVector reductionSyms; - genWsloopClauses(converter, semaCtx, stmtCtx, eval, beginClauses, endClauses, - loc, clauseOps, iv, reductionTypes, reductionSyms); + genWsloopClauses(converter, semaCtx, stmtCtx, eval, clauses, loc, clauseOps, + iv, reductionTypes, reductionSyms); - auto *nestedEval = getCollapsedLoopEval(eval, getCollapseValue(beginClauses)); + auto *nestedEval = getCollapsedLoopEval(eval, getCollapseValue(clauses)); auto ivCallback = [&](mlir::Operation *op) { return genLoopAndReductionVars(op, converter, loc, iv, reductionSyms, @@ -1836,7 +1822,7 @@ genWsloopOp(Fortran::lower::AbstractConverter &converter, return genOpWithBody( OpWithBodyGenInfo(converter, semaCtx, loc, *nestedEval, llvm::omp::Directive::OMPD_do) - .setClauses(&beginClauses) + .setClauses(&clauses) .setDataSharingProcessor(&dsp) .setReductions(&reductionSyms, &reductionTypes) .setGenRegionEntryCb(ivCallback), @@ -1847,19 +1833,20 @@ genWsloopOp(Fortran::lower::AbstractConverter &converter, // Code generation functions for composite constructs //===----------------------------------------------------------------------===// -static void genCompositeDistributeParallelDo( - Fortran::lower::AbstractConverter &converter, - Fortran::semantics::SemanticsContext &semaCtx, - Fortran::lower::pft::Evaluation &eval, const List &beginClauses, - const List &endClauses, mlir::Location loc) { +static void +genCompositeDistributeParallelDo(Fortran::lower::AbstractConverter &converter, + Fortran::semantics::SemanticsContext &semaCtx, + Fortran::lower::pft::Evaluation &eval, + const List &clauses, + mlir::Location loc) { TODO(loc, "Composite DISTRIBUTE PARALLEL DO"); } static void genCompositeDistributeParallelDoSimd( Fortran::lower::AbstractConverter &converter, Fortran::semantics::SemanticsContext &semaCtx, - Fortran::lower::pft::Evaluation &eval, const List &beginClauses, - const List &endClauses, mlir::Location loc) { + Fortran::lower::pft::Evaluation &eval, const List &clauses, + mlir::Location loc) { TODO(loc, "Composite DISTRIBUTE PARALLEL DO SIMD"); } @@ -1867,18 +1854,16 @@ static void genCompositeDistributeSimd(Fortran::lower::AbstractConverter &converter, Fortran::semantics::SemanticsContext &semaCtx, Fortran::lower::pft::Evaluation &eval, - const List &beginClauses, - const List &endClauses, mlir::Location loc) { + const List &clauses, mlir::Location loc) { TODO(loc, "Composite DISTRIBUTE SIMD"); } static void genCompositeDoSimd(Fortran::lower::AbstractConverter &converter, Fortran::semantics::SemanticsContext &semaCtx, Fortran::lower::pft::Evaluation &eval, - const List &beginClauses, - const List &endClauses, + const List &clauses, mlir::Location loc) { - ClauseProcessor cp(converter, semaCtx, beginClauses); + ClauseProcessor cp(converter, semaCtx, clauses); cp.processTODO( loc, llvm::omp::OMPD_do_simd); @@ -1890,15 +1875,14 @@ static void genCompositeDoSimd(Fortran::lower::AbstractConverter &converter, // When support for vectorization is enabled, then we need to add handling of // if clause. Currently if clause can be skipped because we always assume // SIMD length = 1. - genWsloopOp(converter, semaCtx, eval, loc, beginClauses, endClauses); + genWsloopOp(converter, semaCtx, eval, loc, clauses); } static void genCompositeTaskloopSimd(Fortran::lower::AbstractConverter &converter, Fortran::semantics::SemanticsContext &semaCtx, Fortran::lower::pft::Evaluation &eval, - const List &beginClauses, - const List &endClauses, mlir::Location loc) { + const List &clauses, mlir::Location loc) { TODO(loc, "Composite TASKLOOP SIMD"); } @@ -2170,49 +2154,44 @@ genOMP(Fortran::lower::AbstractConverter &converter, converter.genLocation(beginBlockDirective.source); const auto origDirective = std::get(beginBlockDirective.t).v; - List beginClauses = makeClauses( + List clauses = makeClauses( std::get(beginBlockDirective.t), semaCtx); - List endClauses = makeClauses( - std::get(endBlockDirective.t), semaCtx); + clauses.append(makeClauses( + std::get(endBlockDirective.t), semaCtx)); assert(llvm::omp::blockConstructSet.test(origDirective) && "Expected block construct"); - for (const Clause &clause : beginClauses) { + for (const Clause &clause : clauses) { mlir::Location clauseLocation = converter.genLocation(clause.source); - if (!std::get_if(&clause.u) && - !std::get_if(&clause.u) && - !std::get_if(&clause.u) && - !std::get_if(&clause.u) && - !std::get_if(&clause.u) && - !std::get_if(&clause.u) && - !std::get_if(&clause.u) && - !std::get_if(&clause.u) && - !std::get_if(&clause.u) && - !std::get_if(&clause.u) && - !std::get_if(&clause.u) && - !std::get_if(&clause.u) && - !std::get_if(&clause.u) && - !std::get_if(&clause.u) && - !std::get_if(&clause.u) && - !std::get_if(&clause.u) && - !std::get_if(&clause.u) && - !std::get_if(&clause.u) && - !std::get_if(&clause.u) && - !std::get_if(&clause.u) && - !std::get_if(&clause.u) && - !std::get_if(&clause.u)) { + if (!std::holds_alternative(clause.u) && + !std::holds_alternative(clause.u) && + !std::holds_alternative(clause.u) && + !std::holds_alternative(clause.u) && + !std::holds_alternative(clause.u) && + !std::holds_alternative(clause.u) && + !std::holds_alternative(clause.u) && + !std::holds_alternative(clause.u) && + !std::holds_alternative(clause.u) && + !std::holds_alternative(clause.u) && + !std::holds_alternative(clause.u) && + !std::holds_alternative(clause.u) && + !std::holds_alternative(clause.u) && + !std::holds_alternative(clause.u) && + !std::holds_alternative(clause.u) && + !std::holds_alternative(clause.u) && + !std::holds_alternative(clause.u) && + !std::holds_alternative(clause.u) && + !std::holds_alternative(clause.u) && + !std::holds_alternative(clause.u) && + !std::holds_alternative(clause.u) && + !std::holds_alternative(clause.u) && + !std::holds_alternative(clause.u) && + !std::holds_alternative(clause.u)) { TODO(clauseLocation, "OpenMP Block construct clause"); } } - for (const Clause &clause : endClauses) { - mlir::Location clauseLocation = converter.genLocation(clause.source); - if (!std::get_if(&clause.u) && - !std::get_if(&clause.u)) - TODO(clauseLocation, "OpenMP Block construct clause"); - } - std::optional nextDir = origDirective; bool outermostLeafConstruct = true; while (nextDir) { @@ -2228,44 +2207,42 @@ genOMP(Fortran::lower::AbstractConverter &converter, case llvm::omp::Directive::OMPD_ordered: // 2.17.9 ORDERED construct. genOrderedRegionOp(converter, semaCtx, eval, genNested, currentLocation, - beginClauses); + clauses); break; case llvm::omp::Directive::OMPD_parallel: // 2.6 PARALLEL construct. genParallelOp(converter, symTable, semaCtx, eval, genNested, - currentLocation, beginClauses, outerCombined); + currentLocation, clauses, outerCombined); break; case llvm::omp::Directive::OMPD_single: // 2.8.2 SINGLE construct. genSingleOp(converter, semaCtx, eval, genNested, currentLocation, - beginClauses, endClauses); + clauses); break; case llvm::omp::Directive::OMPD_target: // 2.12.5 TARGET construct. - genTargetOp(converter, semaCtx, eval, genNested, currentLocation, - beginClauses, outerCombined); + genTargetOp(converter, semaCtx, eval, genNested, currentLocation, clauses, + outerCombined); break; case llvm::omp::Directive::OMPD_target_data: // 2.12.2 TARGET DATA construct. genTargetDataOp(converter, semaCtx, eval, genNested, currentLocation, - beginClauses); + clauses); break; case llvm::omp::Directive::OMPD_task: // 2.10.1 TASK construct. - genTaskOp(converter, semaCtx, eval, genNested, currentLocation, - beginClauses); + genTaskOp(converter, semaCtx, eval, genNested, currentLocation, clauses); break; case llvm::omp::Directive::OMPD_taskgroup: // 2.17.6 TASKGROUP construct. genTaskgroupOp(converter, semaCtx, eval, genNested, currentLocation, - beginClauses); + clauses); break; case llvm::omp::Directive::OMPD_teams: // 2.7 TEAMS construct. // FIXME Pass the outerCombined argument or rename it to better describe // what it represents if it must always be `false` in this context. - genTeamsOp(converter, semaCtx, eval, genNested, currentLocation, - beginClauses); + genTeamsOp(converter, semaCtx, eval, genNested, currentLocation, clauses); break; case llvm::omp::Directive::OMPD_workshare: // 2.8.3 WORKSHARE construct. @@ -2273,7 +2250,7 @@ genOMP(Fortran::lower::AbstractConverter &converter, // implementation for this feature will come later. For the codes // that use this construct, add a single construct for now. genSingleOp(converter, semaCtx, eval, genNested, currentLocation, - beginClauses, endClauses); + clauses); break; default: llvm_unreachable("Unexpected block construct"); @@ -2315,7 +2292,7 @@ static void genOMP(Fortran::lower::AbstractConverter &converter, const Fortran::parser::OpenMPLoopConstruct &loopConstruct) { const auto &beginLoopDirective = std::get(loopConstruct.t); - List beginClauses = makeClauses( + List clauses = makeClauses( std::get(beginLoopDirective.t), semaCtx); mlir::Location currentLocation = converter.genLocation(beginLoopDirective.source); @@ -2325,16 +2302,13 @@ static void genOMP(Fortran::lower::AbstractConverter &converter, assert(llvm::omp::loopConstructSet.test(origDirective) && "Expected loop construct"); - List endClauses = [&]() { - if (auto &endLoopDirective = - std::get>( - loopConstruct.t)) { - return makeClauses( - std::get(endLoopDirective->t), - semaCtx); - } - return List{}; - }(); + if (auto &endLoopDirective = + std::get>( + loopConstruct.t)) { + clauses.append(makeClauses( + std::get(endLoopDirective->t), + semaCtx)); + } std::optional nextDir = origDirective; while (nextDir) { @@ -2345,29 +2319,27 @@ static void genOMP(Fortran::lower::AbstractConverter &converter, switch (leafDir) { case llvm::omp::Directive::OMPD_distribute_parallel_do: // 2.9.4.3 DISTRIBUTE PARALLEL Worksharing-Loop construct. - genCompositeDistributeParallelDo(converter, semaCtx, eval, beginClauses, - endClauses, currentLocation); + genCompositeDistributeParallelDo(converter, semaCtx, eval, clauses, + currentLocation); break; case llvm::omp::Directive::OMPD_distribute_parallel_do_simd: // 2.9.4.4 DISTRIBUTE PARALLEL Worksharing-Loop SIMD construct. - genCompositeDistributeParallelDoSimd(converter, semaCtx, eval, - beginClauses, endClauses, + genCompositeDistributeParallelDoSimd(converter, semaCtx, eval, clauses, currentLocation); break; case llvm::omp::Directive::OMPD_distribute_simd: // 2.9.4.2 DISTRIBUTE SIMD construct. - genCompositeDistributeSimd(converter, semaCtx, eval, beginClauses, - endClauses, currentLocation); + genCompositeDistributeSimd(converter, semaCtx, eval, clauses, + currentLocation); break; case llvm::omp::Directive::OMPD_do_simd: // 2.9.3.2 Worksharing-Loop SIMD construct. - genCompositeDoSimd(converter, semaCtx, eval, beginClauses, endClauses, - currentLocation); + genCompositeDoSimd(converter, semaCtx, eval, clauses, currentLocation); break; case llvm::omp::Directive::OMPD_taskloop_simd: // 2.10.3 TASKLOOP SIMD construct. - genCompositeTaskloopSimd(converter, semaCtx, eval, beginClauses, - endClauses, currentLocation); + genCompositeTaskloopSimd(converter, semaCtx, eval, clauses, + currentLocation); break; default: llvm_unreachable("Unexpected composite construct"); @@ -2378,12 +2350,11 @@ static void genOMP(Fortran::lower::AbstractConverter &converter, case llvm::omp::Directive::OMPD_distribute: // 2.9.4.1 DISTRIBUTE construct. genDistributeOp(converter, semaCtx, eval, genNested, currentLocation, - beginClauses); + clauses); break; case llvm::omp::Directive::OMPD_do: // 2.9.2 Worksharing-Loop construct. - genWsloopOp(converter, semaCtx, eval, currentLocation, beginClauses, - endClauses); + genWsloopOp(converter, semaCtx, eval, currentLocation, clauses); break; case llvm::omp::Directive::OMPD_parallel: // 2.6 PARALLEL construct. @@ -2392,21 +2363,21 @@ static void genOMP(Fortran::lower::AbstractConverter &converter, // Maybe rename the argument if it represents something else or // initialize it properly. genParallelOp(converter, symTable, semaCtx, eval, genNested, - currentLocation, beginClauses, + currentLocation, clauses, /*outerCombined=*/true); break; case llvm::omp::Directive::OMPD_simd: // 2.9.3.1 SIMD construct. - genSimdOp(converter, semaCtx, eval, currentLocation, beginClauses); + genSimdOp(converter, semaCtx, eval, currentLocation, clauses); break; case llvm::omp::Directive::OMPD_target: // 2.12.5 TARGET construct. genTargetOp(converter, semaCtx, eval, genNested, currentLocation, - beginClauses, /*outerCombined=*/true); + clauses, /*outerCombined=*/true); break; case llvm::omp::Directive::OMPD_taskloop: // 2.10.2 TASKLOOP construct. - genTaskloopOp(converter, semaCtx, eval, currentLocation, beginClauses); + genTaskloopOp(converter, semaCtx, eval, currentLocation, clauses); break; case llvm::omp::Directive::OMPD_teams: // 2.7 TEAMS construct. @@ -2415,7 +2386,7 @@ static void genOMP(Fortran::lower::AbstractConverter &converter, // Maybe rename the argument if it represents something else or // initialize it properly. genTeamsOp(converter, semaCtx, eval, genNested, currentLocation, - beginClauses, /*outerCombined=*/true); + clauses, /*outerCombined=*/true); break; case llvm::omp::Directive::OMPD_loop: case llvm::omp::Directive::OMPD_masked: @@ -2451,16 +2422,20 @@ genOMP(Fortran::lower::AbstractConverter &converter, const Fortran::parser::OpenMPSectionsConstruct §ionsConstruct) { const auto &beginSectionsDirective = std::get(sectionsConstruct.t); - List beginClauses = makeClauses( + List clauses = makeClauses( std::get(beginSectionsDirective.t), semaCtx); + const auto &endSectionsDirective = + std::get(sectionsConstruct.t); + clauses.append(makeClauses( + std::get(endSectionsDirective.t), + semaCtx)); // Process clauses before optional omp.parallel, so that new variables are // allocated outside of the parallel region mlir::Location currentLocation = converter.getCurrentLocation(); mlir::omp::SectionsClauseOps clauseOps; - genSectionsClauses(converter, semaCtx, beginClauses, currentLocation, - /*clausesFromBeginSections=*/true, clauseOps); + genSectionsClauses(converter, semaCtx, clauses, currentLocation, clauseOps); // Parallel wrapper of PARALLEL SECTIONS construct llvm::omp::Directive dir = @@ -2468,16 +2443,8 @@ genOMP(Fortran::lower::AbstractConverter &converter, .v; if (dir == llvm::omp::Directive::OMPD_parallel_sections) { genParallelOp(converter, symTable, semaCtx, eval, - /*genNested=*/false, currentLocation, beginClauses, + /*genNested=*/false, currentLocation, clauses, /*outerCombined=*/true); - } else { - const auto &endSectionsDirective = - std::get(sectionsConstruct.t); - List endClauses = makeClauses( - std::get(endSectionsDirective.t), - semaCtx); - genSectionsClauses(converter, semaCtx, endClauses, currentLocation, - /*clausesFromBeginSections=*/false, clauseOps); } // SECTIONS construct. @@ -2492,7 +2459,7 @@ genOMP(Fortran::lower::AbstractConverter &converter, llvm::zip(sectionBlocks.v, eval.getNestedEvaluations())) { symTable.pushScope(); genSectionOp(converter, semaCtx, neval, /*genNested=*/true, currentLocation, - beginClauses); + clauses); symTable.popScope(); firOpBuilder.restoreInsertionPoint(ip); } -- GitLab From f94ed6f7977305db8fa6b48a85c9db2b8cc4d3b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix-Antoine=20Constantin?= <60141446+felix642@users.noreply.github.com> Date: Mon, 22 Apr 2024 14:05:32 -0400 Subject: [PATCH 015/732] [clang-tidy] Improved --verify-config when using literal style in config file (#85591) Specifying checks using the literal style (|) in the clang-tidy config file is currently supported but was not implemented for the --verify-config options. This means that clang-tidy would work properly but, using the --verify-config option would raise an error due to some checks not being parsed properly. Fixes #53737 --- clang-tools-extra/clang-tidy/GlobList.cpp | 14 +++-- clang-tools-extra/clang-tidy/GlobList.h | 4 ++ .../clang-tidy/tool/ClangTidyMain.cpp | 57 ++++++------------- clang-tools-extra/docs/ReleaseNotes.rst | 3 + .../infrastructure/verify-config.cpp | 12 ++++ 5 files changed, 45 insertions(+), 45 deletions(-) diff --git a/clang-tools-extra/clang-tidy/GlobList.cpp b/clang-tools-extra/clang-tidy/GlobList.cpp index dfe3f7c505b1..8f09ee075bbd 100644 --- a/clang-tools-extra/clang-tidy/GlobList.cpp +++ b/clang-tools-extra/clang-tidy/GlobList.cpp @@ -19,12 +19,17 @@ static bool consumeNegativeIndicator(StringRef &GlobList) { return GlobList.consume_front("-"); } -// Converts first glob from the comma-separated list of globs to Regex and -// removes it and the trailing comma from the GlobList. -static llvm::Regex consumeGlob(StringRef &GlobList) { +// Extracts the first glob from the comma-separated list of globs, +// removes it and the trailing comma from the GlobList and +// returns the extracted glob. +static llvm::StringRef extractNextGlob(StringRef &GlobList) { StringRef UntrimmedGlob = GlobList.substr(0, GlobList.find_first_of(",\n")); StringRef Glob = UntrimmedGlob.trim(); GlobList = GlobList.substr(UntrimmedGlob.size() + 1); + return Glob; +} + +static llvm::Regex createRegexFromGlob(StringRef &Glob) { SmallString<128> RegexText("^"); StringRef MetaChars("()^$|*+?.[]\\{}"); for (char C : Glob) { @@ -43,7 +48,8 @@ GlobList::GlobList(StringRef Globs, bool KeepNegativeGlobs /* =true */) { do { GlobListItem Item; Item.IsPositive = !consumeNegativeIndicator(Globs); - Item.Regex = consumeGlob(Globs); + Item.Text = extractNextGlob(Globs); + Item.Regex = createRegexFromGlob(Item.Text); if (Item.IsPositive || KeepNegativeGlobs) Items.push_back(std::move(Item)); } while (!Globs.empty()); diff --git a/clang-tools-extra/clang-tidy/GlobList.h b/clang-tools-extra/clang-tidy/GlobList.h index 44af182e43b0..4317928270ad 100644 --- a/clang-tools-extra/clang-tidy/GlobList.h +++ b/clang-tools-extra/clang-tidy/GlobList.h @@ -44,8 +44,12 @@ private: struct GlobListItem { bool IsPositive; llvm::Regex Regex; + llvm::StringRef Text; }; SmallVector Items; + +public: + const SmallVectorImpl &getItems() const { return Items; }; }; /// A \p GlobList that caches search results, so that search is performed only diff --git a/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp b/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp index 9f3d6b6db6cb..f82f4417141d 100644 --- a/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp +++ b/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp @@ -454,52 +454,27 @@ static constexpr StringLiteral VerifyConfigWarningEnd = " [-verify-config]\n"; static bool verifyChecks(const StringSet<> &AllChecks, StringRef CheckGlob, StringRef Source) { - llvm::StringRef Cur, Rest; + GlobList Globs(CheckGlob); bool AnyInvalid = false; - for (std::tie(Cur, Rest) = CheckGlob.split(','); - !(Cur.empty() && Rest.empty()); std::tie(Cur, Rest) = Rest.split(',')) { - Cur = Cur.trim(); - if (Cur.empty()) + for (const auto &Item : Globs.getItems()) { + if (Item.Text.starts_with("clang-diagnostic")) continue; - Cur.consume_front("-"); - if (Cur.starts_with("clang-diagnostic")) - continue; - if (Cur.contains('*')) { - SmallString<128> RegexText("^"); - StringRef MetaChars("()^$|*+?.[]\\{}"); - for (char C : Cur) { - if (C == '*') - RegexText.push_back('.'); - else if (MetaChars.contains(C)) - RegexText.push_back('\\'); - RegexText.push_back(C); - } - RegexText.push_back('$'); - llvm::Regex Glob(RegexText); - std::string Error; - if (!Glob.isValid(Error)) { - AnyInvalid = true; - llvm::WithColor::error(llvm::errs(), Source) - << "building check glob '" << Cur << "' " << Error << "'\n"; - continue; - } - if (llvm::none_of(AllChecks.keys(), - [&Glob](StringRef S) { return Glob.match(S); })) { - AnyInvalid = true; + if (llvm::none_of(AllChecks.keys(), + [&Item](StringRef S) { return Item.Regex.match(S); })) { + AnyInvalid = true; + if (Item.Text.contains('*')) llvm::WithColor::warning(llvm::errs(), Source) - << "check glob '" << Cur << "' doesn't match any known check" + << "check glob '" << Item.Text << "' doesn't match any known check" << VerifyConfigWarningEnd; + else { + llvm::raw_ostream &Output = + llvm::WithColor::warning(llvm::errs(), Source) + << "unknown check '" << Item.Text << '\''; + llvm::StringRef Closest = closest(Item.Text, AllChecks); + if (!Closest.empty()) + Output << "; did you mean '" << Closest << '\''; + Output << VerifyConfigWarningEnd; } - } else { - if (AllChecks.contains(Cur)) - continue; - AnyInvalid = true; - llvm::raw_ostream &Output = llvm::WithColor::warning(llvm::errs(), Source) - << "unknown check '" << Cur << '\''; - llvm::StringRef Closest = closest(Cur, AllChecks); - if (!Closest.empty()) - Output << "; did you mean '" << Closest << '\''; - Output << VerifyConfigWarningEnd; } } return AnyInvalid; diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 9ef1d38d3c45..f3f9a81f9a8e 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -103,6 +103,9 @@ Improvements to clang-tidy - Improved :program:`check_clang_tidy.py` script. Added argument `-export-fixes` to aid in clang-tidy and test development. +- Fixed ``--verify-config`` option not properly parsing checks when using the + literal operator in the ``.clang-tidy`` config. + New checks ^^^^^^^^^^ diff --git a/clang-tools-extra/test/clang-tidy/infrastructure/verify-config.cpp b/clang-tools-extra/test/clang-tidy/infrastructure/verify-config.cpp index 421f8641281a..365928598648 100644 --- a/clang-tools-extra/test/clang-tidy/infrastructure/verify-config.cpp +++ b/clang-tools-extra/test/clang-tidy/infrastructure/verify-config.cpp @@ -18,3 +18,15 @@ // CHECK-VERIFY: command-line option '-checks': warning: check glob 'bad*glob' doesn't match any known check [-verify-config] // CHECK-VERIFY: command-line option '-checks': warning: unknown check 'llvm-includeorder'; did you mean 'llvm-include-order' [-verify-config] // CHECK-VERIFY: command-line option '-checks': warning: unknown check 'my-made-up-check' [-verify-config] + +// RUN: echo -e 'Checks: |\n bugprone-argument-comment\n bugprone-assert-side-effect,\n bugprone-bool-pointer-implicit-conversion\n readability-use-anyof*' > %T/MyClangTidyConfig +// RUN: clang-tidy -verify-config \ +// RUN: --config-file=%T/MyClangTidyConfig | FileCheck %s -check-prefix=CHECK-VERIFY-BLOCK-OK +// CHECK-VERIFY-BLOCK-OK: No config errors detected. + +// RUN: echo -e 'Checks: |\n bugprone-arguments-*\n bugprone-assert-side-effects\n bugprone-bool-pointer-implicit-conversion' > %T/MyClangTidyConfigBad +// RUN: not clang-tidy -verify-config \ +// RUN: --config-file=%T/MyClangTidyConfigBad 2>&1 | FileCheck %s -check-prefix=CHECK-VERIFY-BLOCK-BAD +// CHECK-VERIFY-BLOCK-BAD: command-line option '-config': warning: check glob 'bugprone-arguments-*' doesn't match any known check [-verify-config] +// CHECK-VERIFY-BLOCK-BAD: command-line option '-config': warning: unknown check 'bugprone-assert-side-effects'; did you mean 'bugprone-assert-side-effect' [-verify-config] + -- GitLab From 758d97dce0c669a0ba6927728b40030a76acb144 Mon Sep 17 00:00:00 2001 From: YunQiang Su Date: Tue, 23 Apr 2024 02:08:12 +0800 Subject: [PATCH 016/732] [MIPS]: Rework atomic max/min expand for subword (#89575) The current code is so buggy: it can work for few cases. The problems include: 1. ll/sc works on a whole word, while other parts other than we rmw are dropped. 2. The oprands are not well zero-extended for unsigned ops. 3. It doesn't work for big-endian, as the postion of subword differs with little endian. And in fact, we can set the return value correct in ll/sc scope, so we can skip the sinkMBB. --- llvm/lib/Target/Mips/MipsExpandPseudo.cpp | 114 +- llvm/test/CodeGen/Mips/atomic-min-max.ll | 1475 +++++++++++---------- 2 files changed, 823 insertions(+), 766 deletions(-) diff --git a/llvm/lib/Target/Mips/MipsExpandPseudo.cpp b/llvm/lib/Target/Mips/MipsExpandPseudo.cpp index c30129743a96..d33852a04baf 100644 --- a/llvm/lib/Target/Mips/MipsExpandPseudo.cpp +++ b/llvm/lib/Target/Mips/MipsExpandPseudo.cpp @@ -342,6 +342,7 @@ bool MipsExpandPseudo::expandAtomicBinOpSubword( bool IsMin = false; bool IsMax = false; bool IsUnsigned = false; + bool DestOK = false; unsigned Opcode = 0; switch (I->getOpcode()) { @@ -388,6 +389,7 @@ bool MipsExpandPseudo::expandAtomicBinOpSubword( Opcode = Mips::XOR; break; case Mips::ATOMIC_LOAD_UMIN_I8_POSTRA: + SEOp = Mips::SEB; IsUnsigned = true; IsMin = true; break; @@ -403,6 +405,7 @@ bool MipsExpandPseudo::expandAtomicBinOpSubword( IsMin = true; break; case Mips::ATOMIC_LOAD_UMAX_I8_POSTRA: + SEOp = Mips::SEB; IsUnsigned = true; IsMax = true; break; @@ -473,48 +476,38 @@ bool MipsExpandPseudo::expandAtomicBinOpSubword( unsigned SELOldVal = IsMax ? SELEQZ : SELNEZ; unsigned MOVIncr = IsMax ? MOVN : MOVZ; - // For little endian we need to clear uninterested bits. - if (STI->isLittle()) { - if (!IsUnsigned) { - BuildMI(loopMBB, DL, TII->get(Mips::SRAV), OldVal) - .addReg(OldVal) - .addReg(ShiftAmnt); - BuildMI(loopMBB, DL, TII->get(Mips::SRAV), Incr) - .addReg(Incr) - .addReg(ShiftAmnt); - if (STI->hasMips32r2()) { - BuildMI(loopMBB, DL, TII->get(SEOp), OldVal).addReg(OldVal); - BuildMI(loopMBB, DL, TII->get(SEOp), Incr).addReg(Incr); - } else { - const unsigned ShiftImm = SEOp == Mips::SEH ? 16 : 24; - BuildMI(loopMBB, DL, TII->get(Mips::SLL), OldVal) - .addReg(OldVal, RegState::Kill) - .addImm(ShiftImm); - BuildMI(loopMBB, DL, TII->get(Mips::SRA), OldVal) - .addReg(OldVal, RegState::Kill) - .addImm(ShiftImm); - BuildMI(loopMBB, DL, TII->get(Mips::SLL), Incr) - .addReg(Incr, RegState::Kill) - .addImm(ShiftImm); - BuildMI(loopMBB, DL, TII->get(Mips::SRA), Incr) - .addReg(Incr, RegState::Kill) - .addImm(ShiftImm); - } - } else { - // and OldVal, OldVal, Mask - // and Incr, Incr, Mask - BuildMI(loopMBB, DL, TII->get(Mips::AND), OldVal) - .addReg(OldVal) - .addReg(Mask); - BuildMI(loopMBB, DL, TII->get(Mips::AND), Incr) - .addReg(Incr) - .addReg(Mask); - } + BuildMI(loopMBB, DL, TII->get(Mips::SRAV), StoreVal) + .addReg(OldVal) + .addReg(ShiftAmnt); + if (STI->hasMips32r2() && !IsUnsigned) { + BuildMI(loopMBB, DL, TII->get(SEOp), StoreVal).addReg(StoreVal); + } else if (STI->hasMips32r2() && IsUnsigned) { + const unsigned OpMask = SEOp == Mips::SEH ? 0xffff : 0xff; + BuildMI(loopMBB, DL, TII->get(Mips::ANDi), StoreVal) + .addReg(StoreVal) + .addImm(OpMask); + } else { + const unsigned ShiftImm = SEOp == Mips::SEH ? 16 : 24; + const unsigned SROp = IsUnsigned ? Mips::SRL : Mips::SRA; + BuildMI(loopMBB, DL, TII->get(Mips::SLL), StoreVal) + .addReg(StoreVal, RegState::Kill) + .addImm(ShiftImm); + BuildMI(loopMBB, DL, TII->get(SROp), StoreVal) + .addReg(StoreVal, RegState::Kill) + .addImm(ShiftImm); } - // unsigned: sltu Scratch4, oldVal, Incr - // signed: slt Scratch4, oldVal, Incr + BuildMI(loopMBB, DL, TII->get(Mips::OR), Dest) + .addReg(Mips::ZERO) + .addReg(StoreVal); + DestOK = true; + BuildMI(loopMBB, DL, TII->get(Mips::SLLV), StoreVal) + .addReg(StoreVal) + .addReg(ShiftAmnt); + + // unsigned: sltu Scratch4, StoreVal, Incr + // signed: slt Scratch4, StoreVal, Incr BuildMI(loopMBB, DL, TII->get(SLTScratch4), Scratch4) - .addReg(OldVal) + .addReg(StoreVal) .addReg(Incr); if (STI->hasMips64r6() || STI->hasMips32r6()) { @@ -525,7 +518,7 @@ bool MipsExpandPseudo::expandAtomicBinOpSubword( // seleqz Scratch4, Incr, Scratch4 // or BinOpRes, BinOpRes, Scratch4 BuildMI(loopMBB, DL, TII->get(SELOldVal), BinOpRes) - .addReg(OldVal) + .addReg(StoreVal) .addReg(Scratch4); BuildMI(loopMBB, DL, TII->get(SELIncr), Scratch4) .addReg(Incr) @@ -534,12 +527,12 @@ bool MipsExpandPseudo::expandAtomicBinOpSubword( .addReg(BinOpRes) .addReg(Scratch4); } else { - // max: move BinOpRes, OldVal + // max: move BinOpRes, StoreVal // movn BinOpRes, Incr, Scratch4, BinOpRes - // min: move BinOpRes, OldVal + // min: move BinOpRes, StoreVal // movz BinOpRes, Incr, Scratch4, BinOpRes BuildMI(loopMBB, DL, TII->get(OR), BinOpRes) - .addReg(OldVal) + .addReg(StoreVal) .addReg(Mips::ZERO); BuildMI(loopMBB, DL, TII->get(MOVIncr), BinOpRes) .addReg(Incr) @@ -586,23 +579,24 @@ bool MipsExpandPseudo::expandAtomicBinOpSubword( // srl srlres,maskedoldval1,shiftamt // sign_extend dest,srlres - sinkMBB->addSuccessor(exitMBB, BranchProbability::getOne()); - - BuildMI(sinkMBB, DL, TII->get(Mips::AND), Dest) - .addReg(OldVal).addReg(Mask); - BuildMI(sinkMBB, DL, TII->get(Mips::SRLV), Dest) - .addReg(Dest).addReg(ShiftAmnt); + if (!DestOK) { + sinkMBB->addSuccessor(exitMBB, BranchProbability::getOne()); + BuildMI(sinkMBB, DL, TII->get(Mips::AND), Dest).addReg(OldVal).addReg(Mask); + BuildMI(sinkMBB, DL, TII->get(Mips::SRLV), Dest) + .addReg(Dest) + .addReg(ShiftAmnt); - if (STI->hasMips32r2()) { - BuildMI(sinkMBB, DL, TII->get(SEOp), Dest).addReg(Dest); - } else { - const unsigned ShiftImm = SEOp == Mips::SEH ? 16 : 24; - BuildMI(sinkMBB, DL, TII->get(Mips::SLL), Dest) - .addReg(Dest, RegState::Kill) - .addImm(ShiftImm); - BuildMI(sinkMBB, DL, TII->get(Mips::SRA), Dest) - .addReg(Dest, RegState::Kill) - .addImm(ShiftImm); + if (STI->hasMips32r2()) { + BuildMI(sinkMBB, DL, TII->get(SEOp), Dest).addReg(Dest); + } else { + const unsigned ShiftImm = SEOp == Mips::SEH ? 16 : 24; + BuildMI(sinkMBB, DL, TII->get(Mips::SLL), Dest) + .addReg(Dest, RegState::Kill) + .addImm(ShiftImm); + BuildMI(sinkMBB, DL, TII->get(Mips::SRA), Dest) + .addReg(Dest, RegState::Kill) + .addImm(ShiftImm); + } } LivePhysRegs LiveRegs; diff --git a/llvm/test/CodeGen/Mips/atomic-min-max.ll b/llvm/test/CodeGen/Mips/atomic-min-max.ll index a96581bdb39a..2f07d70808c1 100644 --- a/llvm/test/CodeGen/Mips/atomic-min-max.ll +++ b/llvm/test/CodeGen/Mips/atomic-min-max.ll @@ -912,8 +912,12 @@ define i16 @test_max_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS-NEXT: $BB4_1: # %entry ; MIPS-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPS-NEXT: ll $2, 0($6) -; MIPS-NEXT: slt $5, $2, $7 -; MIPS-NEXT: move $3, $2 +; MIPS-NEXT: srav $4, $2, $10 +; MIPS-NEXT: seh $4, $4 +; MIPS-NEXT: or $1, $zero, $4 +; MIPS-NEXT: sllv $4, $4, $10 +; MIPS-NEXT: slt $5, $4, $7 +; MIPS-NEXT: move $3, $4 ; MIPS-NEXT: movn $3, $7, $5 ; MIPS-NEXT: and $3, $3, $8 ; MIPS-NEXT: and $4, $2, $9 @@ -922,9 +926,7 @@ define i16 @test_max_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS-NEXT: beqz $4, $BB4_1 ; MIPS-NEXT: nop ; MIPS-NEXT: # %bb.2: # %entry -; MIPS-NEXT: and $1, $2, $8 -; MIPS-NEXT: srlv $1, $1, $10 -; MIPS-NEXT: seh $1, $1 +; MIPS-NEXT: .insn ; MIPS-NEXT: # %bb.3: # %entry ; MIPS-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MIPS-NEXT: # %bb.4: # %entry @@ -952,8 +954,12 @@ define i16 @test_max_16(ptr nocapture %ptr, i16 signext %val) { ; MIPSR6-NEXT: $BB4_1: # %entry ; MIPSR6-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPSR6-NEXT: ll $2, 0($6) -; MIPSR6-NEXT: slt $5, $2, $7 -; MIPSR6-NEXT: seleqz $3, $2, $5 +; MIPSR6-NEXT: srav $4, $2, $10 +; MIPSR6-NEXT: seh $4, $4 +; MIPSR6-NEXT: or $1, $zero, $4 +; MIPSR6-NEXT: sllv $4, $4, $10 +; MIPSR6-NEXT: slt $5, $4, $7 +; MIPSR6-NEXT: seleqz $3, $4, $5 ; MIPSR6-NEXT: selnez $5, $7, $5 ; MIPSR6-NEXT: or $3, $3, $5 ; MIPSR6-NEXT: and $3, $3, $8 @@ -961,10 +967,9 @@ define i16 @test_max_16(ptr nocapture %ptr, i16 signext %val) { ; MIPSR6-NEXT: or $4, $4, $3 ; MIPSR6-NEXT: sc $4, 0($6) ; MIPSR6-NEXT: beqzc $4, $BB4_1 +; MIPSR6-NEXT: nop ; MIPSR6-NEXT: # %bb.2: # %entry -; MIPSR6-NEXT: and $1, $2, $8 -; MIPSR6-NEXT: srlv $1, $1, $10 -; MIPSR6-NEXT: seh $1, $1 +; MIPSR6-NEXT: .insn ; MIPSR6-NEXT: # %bb.3: # %entry ; MIPSR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MIPSR6-NEXT: # %bb.4: # %entry @@ -991,8 +996,12 @@ define i16 @test_max_16(ptr nocapture %ptr, i16 signext %val) { ; MM-NEXT: $BB4_1: # %entry ; MM-NEXT: # =>This Inner Loop Header: Depth=1 ; MM-NEXT: ll $2, 0($6) -; MM-NEXT: slt $5, $2, $7 -; MM-NEXT: or $3, $2, $zero +; MM-NEXT: srav $4, $2, $10 +; MM-NEXT: seh $4, $4 +; MM-NEXT: or $1, $zero, $4 +; MM-NEXT: sllv $4, $4, $10 +; MM-NEXT: slt $5, $4, $7 +; MM-NEXT: or $3, $4, $zero ; MM-NEXT: movn $3, $7, $5 ; MM-NEXT: and $3, $3, $8 ; MM-NEXT: and $4, $2, $9 @@ -1000,9 +1009,7 @@ define i16 @test_max_16(ptr nocapture %ptr, i16 signext %val) { ; MM-NEXT: sc $4, 0($6) ; MM-NEXT: beqzc $4, $BB4_1 ; MM-NEXT: # %bb.2: # %entry -; MM-NEXT: and $1, $2, $8 -; MM-NEXT: srlv $1, $1, $10 -; MM-NEXT: seh $1, $1 +; MM-NEXT: .insn ; MM-NEXT: # %bb.3: # %entry ; MM-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MM-NEXT: # %bb.4: # %entry @@ -1029,8 +1036,12 @@ define i16 @test_max_16(ptr nocapture %ptr, i16 signext %val) { ; MMR6-NEXT: $BB4_1: # %entry ; MMR6-NEXT: # =>This Inner Loop Header: Depth=1 ; MMR6-NEXT: ll $2, 0($6) -; MMR6-NEXT: slt $5, $2, $7 -; MMR6-NEXT: seleqz $3, $2, $5 +; MMR6-NEXT: srav $4, $2, $10 +; MMR6-NEXT: seh $4, $4 +; MMR6-NEXT: or $1, $zero, $4 +; MMR6-NEXT: sllv $4, $4, $10 +; MMR6-NEXT: slt $5, $4, $7 +; MMR6-NEXT: seleqz $3, $4, $5 ; MMR6-NEXT: selnez $5, $7, $5 ; MMR6-NEXT: or $3, $3, $5 ; MMR6-NEXT: and $3, $3, $8 @@ -1039,9 +1050,7 @@ define i16 @test_max_16(ptr nocapture %ptr, i16 signext %val) { ; MMR6-NEXT: sc $4, 0($6) ; MMR6-NEXT: beqc $4, $zero, $BB4_1 ; MMR6-NEXT: # %bb.2: # %entry -; MMR6-NEXT: and $1, $2, $8 -; MMR6-NEXT: srlv $1, $1, $10 -; MMR6-NEXT: seh $1, $1 +; MMR6-NEXT: .insn ; MMR6-NEXT: # %bb.3: # %entry ; MMR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MMR6-NEXT: # %bb.4: # %entry @@ -1067,14 +1076,13 @@ define i16 @test_max_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS32-NEXT: $BB4_1: # %entry ; MIPS32-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPS32-NEXT: ll $2, 0($6) -; MIPS32-NEXT: srav $2, $2, $10 -; MIPS32-NEXT: srav $7, $7, $10 -; MIPS32-NEXT: sll $2, $2, 16 -; MIPS32-NEXT: sra $2, $2, 16 -; MIPS32-NEXT: sll $7, $7, 16 -; MIPS32-NEXT: sra $7, $7, 16 -; MIPS32-NEXT: slt $5, $2, $7 -; MIPS32-NEXT: move $3, $2 +; MIPS32-NEXT: srav $4, $2, $10 +; MIPS32-NEXT: sll $4, $4, 16 +; MIPS32-NEXT: sra $4, $4, 16 +; MIPS32-NEXT: or $1, $zero, $4 +; MIPS32-NEXT: sllv $4, $4, $10 +; MIPS32-NEXT: slt $5, $4, $7 +; MIPS32-NEXT: move $3, $4 ; MIPS32-NEXT: movn $3, $7, $5 ; MIPS32-NEXT: and $3, $3, $8 ; MIPS32-NEXT: and $4, $2, $9 @@ -1083,10 +1091,7 @@ define i16 @test_max_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS32-NEXT: beqz $4, $BB4_1 ; MIPS32-NEXT: nop ; MIPS32-NEXT: # %bb.2: # %entry -; MIPS32-NEXT: and $1, $2, $8 -; MIPS32-NEXT: srlv $1, $1, $10 -; MIPS32-NEXT: sll $1, $1, 16 -; MIPS32-NEXT: sra $1, $1, 16 +; MIPS32-NEXT: .insn ; MIPS32-NEXT: # %bb.3: # %entry ; MIPS32-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MIPS32-NEXT: # %bb.4: # %entry @@ -1095,7 +1100,6 @@ define i16 @test_max_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS32-NEXT: addiu $sp, $sp, 8 ; MIPS32-NEXT: jr $ra ; MIPS32-NEXT: nop - ; ; MIPSEL-LABEL: test_max_16: ; MIPSEL: # %bb.0: # %entry @@ -1114,12 +1118,12 @@ define i16 @test_max_16(ptr nocapture %ptr, i16 signext %val) { ; MIPSEL-NEXT: $BB4_1: # %entry ; MIPSEL-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPSEL-NEXT: ll $2, 0($6) -; MIPSEL-NEXT: srav $2, $2, $10 -; MIPSEL-NEXT: srav $7, $7, $10 -; MIPSEL-NEXT: seh $2, $2 -; MIPSEL-NEXT: seh $7, $7 -; MIPSEL-NEXT: slt $5, $2, $7 -; MIPSEL-NEXT: move $3, $2 +; MIPSEL-NEXT: srav $4, $2, $10 +; MIPSEL-NEXT: seh $4, $4 +; MIPSEL-NEXT: or $1, $zero, $4 +; MIPSEL-NEXT: sllv $4, $4, $10 +; MIPSEL-NEXT: slt $5, $4, $7 +; MIPSEL-NEXT: move $3, $4 ; MIPSEL-NEXT: movn $3, $7, $5 ; MIPSEL-NEXT: and $3, $3, $8 ; MIPSEL-NEXT: and $4, $2, $9 @@ -1128,9 +1132,7 @@ define i16 @test_max_16(ptr nocapture %ptr, i16 signext %val) { ; MIPSEL-NEXT: beqz $4, $BB4_1 ; MIPSEL-NEXT: nop ; MIPSEL-NEXT: # %bb.2: # %entry -; MIPSEL-NEXT: and $1, $2, $8 -; MIPSEL-NEXT: srlv $1, $1, $10 -; MIPSEL-NEXT: seh $1, $1 +; MIPSEL-NEXT: .insn ; MIPSEL-NEXT: # %bb.3: # %entry ; MIPSEL-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MIPSEL-NEXT: # %bb.4: # %entry @@ -1157,12 +1159,12 @@ define i16 @test_max_16(ptr nocapture %ptr, i16 signext %val) { ; MIPSELR6-NEXT: $BB4_1: # %entry ; MIPSELR6-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPSELR6-NEXT: ll $2, 0($6) -; MIPSELR6-NEXT: srav $2, $2, $10 -; MIPSELR6-NEXT: srav $7, $7, $10 -; MIPSELR6-NEXT: seh $2, $2 -; MIPSELR6-NEXT: seh $7, $7 -; MIPSELR6-NEXT: slt $5, $2, $7 -; MIPSELR6-NEXT: seleqz $3, $2, $5 +; MIPSELR6-NEXT: srav $4, $2, $10 +; MIPSELR6-NEXT: seh $4, $4 +; MIPSELR6-NEXT: or $1, $zero, $4 +; MIPSELR6-NEXT: sllv $4, $4, $10 +; MIPSELR6-NEXT: slt $5, $4, $7 +; MIPSELR6-NEXT: seleqz $3, $4, $5 ; MIPSELR6-NEXT: selnez $5, $7, $5 ; MIPSELR6-NEXT: or $3, $3, $5 ; MIPSELR6-NEXT: and $3, $3, $8 @@ -1170,10 +1172,9 @@ define i16 @test_max_16(ptr nocapture %ptr, i16 signext %val) { ; MIPSELR6-NEXT: or $4, $4, $3 ; MIPSELR6-NEXT: sc $4, 0($6) ; MIPSELR6-NEXT: beqzc $4, $BB4_1 +; MIPSELR6-NEXT: nop ; MIPSELR6-NEXT: # %bb.2: # %entry -; MIPSELR6-NEXT: and $1, $2, $8 -; MIPSELR6-NEXT: srlv $1, $1, $10 -; MIPSELR6-NEXT: seh $1, $1 +; MIPSELR6-NEXT: .insn ; MIPSELR6-NEXT: # %bb.3: # %entry ; MIPSELR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MIPSELR6-NEXT: # %bb.4: # %entry @@ -1199,12 +1200,12 @@ define i16 @test_max_16(ptr nocapture %ptr, i16 signext %val) { ; MMEL-NEXT: $BB4_1: # %entry ; MMEL-NEXT: # =>This Inner Loop Header: Depth=1 ; MMEL-NEXT: ll $2, 0($6) -; MMEL-NEXT: srav $2, $2, $10 -; MMEL-NEXT: srav $7, $7, $10 -; MMEL-NEXT: seh $2, $2 -; MMEL-NEXT: seh $7, $7 -; MMEL-NEXT: slt $5, $2, $7 -; MMEL-NEXT: or $3, $2, $zero +; MMEL-NEXT: srav $4, $2, $10 +; MMEL-NEXT: seh $4, $4 +; MMEL-NEXT: or $1, $zero, $4 +; MMEL-NEXT: sllv $4, $4, $10 +; MMEL-NEXT: slt $5, $4, $7 +; MMEL-NEXT: or $3, $4, $zero ; MMEL-NEXT: movn $3, $7, $5 ; MMEL-NEXT: and $3, $3, $8 ; MMEL-NEXT: and $4, $2, $9 @@ -1212,9 +1213,7 @@ define i16 @test_max_16(ptr nocapture %ptr, i16 signext %val) { ; MMEL-NEXT: sc $4, 0($6) ; MMEL-NEXT: beqzc $4, $BB4_1 ; MMEL-NEXT: # %bb.2: # %entry -; MMEL-NEXT: and $1, $2, $8 -; MMEL-NEXT: srlv $1, $1, $10 -; MMEL-NEXT: seh $1, $1 +; MMEL-NEXT: .insn ; MMEL-NEXT: # %bb.3: # %entry ; MMEL-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MMEL-NEXT: # %bb.4: # %entry @@ -1240,12 +1239,12 @@ define i16 @test_max_16(ptr nocapture %ptr, i16 signext %val) { ; MMELR6-NEXT: $BB4_1: # %entry ; MMELR6-NEXT: # =>This Inner Loop Header: Depth=1 ; MMELR6-NEXT: ll $2, 0($6) -; MMELR6-NEXT: srav $2, $2, $10 -; MMELR6-NEXT: srav $7, $7, $10 -; MMELR6-NEXT: seh $2, $2 -; MMELR6-NEXT: seh $7, $7 -; MMELR6-NEXT: slt $5, $2, $7 -; MMELR6-NEXT: seleqz $3, $2, $5 +; MMELR6-NEXT: srav $4, $2, $10 +; MMELR6-NEXT: seh $4, $4 +; MMELR6-NEXT: or $1, $zero, $4 +; MMELR6-NEXT: sllv $4, $4, $10 +; MMELR6-NEXT: slt $5, $4, $7 +; MMELR6-NEXT: seleqz $3, $4, $5 ; MMELR6-NEXT: selnez $5, $7, $5 ; MMELR6-NEXT: or $3, $3, $5 ; MMELR6-NEXT: and $3, $3, $8 @@ -1254,9 +1253,7 @@ define i16 @test_max_16(ptr nocapture %ptr, i16 signext %val) { ; MMELR6-NEXT: sc $4, 0($6) ; MMELR6-NEXT: beqc $4, $zero, $BB4_1 ; MMELR6-NEXT: # %bb.2: # %entry -; MMELR6-NEXT: and $1, $2, $8 -; MMELR6-NEXT: srlv $1, $1, $10 -; MMELR6-NEXT: seh $1, $1 +; MMELR6-NEXT: .insn ; MMELR6-NEXT: # %bb.3: # %entry ; MMELR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MMELR6-NEXT: # %bb.4: # %entry @@ -1283,8 +1280,12 @@ define i16 @test_max_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS64-NEXT: .LBB4_1: # %entry ; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPS64-NEXT: ll $2, 0($6) -; MIPS64-NEXT: slt $5, $2, $7 -; MIPS64-NEXT: move $3, $2 +; MIPS64-NEXT: srav $4, $2, $10 +; MIPS64-NEXT: seh $4, $4 +; MIPS64-NEXT: or $1, $zero, $4 +; MIPS64-NEXT: sllv $4, $4, $10 +; MIPS64-NEXT: slt $5, $4, $7 +; MIPS64-NEXT: move $3, $4 ; MIPS64-NEXT: movn $3, $7, $5 ; MIPS64-NEXT: and $3, $3, $8 ; MIPS64-NEXT: and $4, $2, $9 @@ -1293,9 +1294,7 @@ define i16 @test_max_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS64-NEXT: beqz $4, .LBB4_1 ; MIPS64-NEXT: nop ; MIPS64-NEXT: # %bb.2: # %entry -; MIPS64-NEXT: and $1, $2, $8 -; MIPS64-NEXT: srlv $1, $1, $10 -; MIPS64-NEXT: seh $1, $1 +; MIPS64-NEXT: .insn ; MIPS64-NEXT: # %bb.3: # %entry ; MIPS64-NEXT: sw $1, 12($sp) # 4-byte Folded Spill ; MIPS64-NEXT: # %bb.4: # %entry @@ -1323,8 +1322,12 @@ define i16 @test_max_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS64R6-NEXT: .LBB4_1: # %entry ; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPS64R6-NEXT: ll $2, 0($6) -; MIPS64R6-NEXT: slt $5, $2, $7 -; MIPS64R6-NEXT: seleqz $3, $2, $5 +; MIPS64R6-NEXT: srav $4, $2, $10 +; MIPS64R6-NEXT: seh $4, $4 +; MIPS64R6-NEXT: or $1, $zero, $4 +; MIPS64R6-NEXT: sllv $4, $4, $10 +; MIPS64R6-NEXT: slt $5, $4, $7 +; MIPS64R6-NEXT: seleqz $3, $4, $5 ; MIPS64R6-NEXT: selnez $5, $7, $5 ; MIPS64R6-NEXT: or $3, $3, $5 ; MIPS64R6-NEXT: and $3, $3, $8 @@ -1332,10 +1335,9 @@ define i16 @test_max_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS64R6-NEXT: or $4, $4, $3 ; MIPS64R6-NEXT: sc $4, 0($6) ; MIPS64R6-NEXT: beqzc $4, .LBB4_1 +; MIPS64R6-NEXT: nop ; MIPS64R6-NEXT: # %bb.2: # %entry -; MIPS64R6-NEXT: and $1, $2, $8 -; MIPS64R6-NEXT: srlv $1, $1, $10 -; MIPS64R6-NEXT: seh $1, $1 +; MIPS64R6-NEXT: .insn ; MIPS64R6-NEXT: # %bb.3: # %entry ; MIPS64R6-NEXT: sw $1, 12($sp) # 4-byte Folded Spill ; MIPS64R6-NEXT: # %bb.4: # %entry @@ -1361,12 +1363,12 @@ define i16 @test_max_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS64EL-NEXT: .LBB4_1: # %entry ; MIPS64EL-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPS64EL-NEXT: ll $2, 0($6) -; MIPS64EL-NEXT: srav $2, $2, $10 -; MIPS64EL-NEXT: srav $7, $7, $10 -; MIPS64EL-NEXT: seh $2, $2 -; MIPS64EL-NEXT: seh $7, $7 -; MIPS64EL-NEXT: slt $5, $2, $7 -; MIPS64EL-NEXT: move $3, $2 +; MIPS64EL-NEXT: srav $4, $2, $10 +; MIPS64EL-NEXT: seh $4, $4 +; MIPS64EL-NEXT: or $1, $zero, $4 +; MIPS64EL-NEXT: sllv $4, $4, $10 +; MIPS64EL-NEXT: slt $5, $4, $7 +; MIPS64EL-NEXT: move $3, $4 ; MIPS64EL-NEXT: movn $3, $7, $5 ; MIPS64EL-NEXT: and $3, $3, $8 ; MIPS64EL-NEXT: and $4, $2, $9 @@ -1375,9 +1377,7 @@ define i16 @test_max_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS64EL-NEXT: beqz $4, .LBB4_1 ; MIPS64EL-NEXT: nop ; MIPS64EL-NEXT: # %bb.2: # %entry -; MIPS64EL-NEXT: and $1, $2, $8 -; MIPS64EL-NEXT: srlv $1, $1, $10 -; MIPS64EL-NEXT: seh $1, $1 +; MIPS64EL-NEXT: .insn ; MIPS64EL-NEXT: # %bb.3: # %entry ; MIPS64EL-NEXT: sw $1, 12($sp) # 4-byte Folded Spill ; MIPS64EL-NEXT: # %bb.4: # %entry @@ -1404,12 +1404,12 @@ define i16 @test_max_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS64ELR6-NEXT: .LBB4_1: # %entry ; MIPS64ELR6-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPS64ELR6-NEXT: ll $2, 0($6) -; MIPS64ELR6-NEXT: srav $2, $2, $10 -; MIPS64ELR6-NEXT: srav $7, $7, $10 -; MIPS64ELR6-NEXT: seh $2, $2 -; MIPS64ELR6-NEXT: seh $7, $7 -; MIPS64ELR6-NEXT: slt $5, $2, $7 -; MIPS64ELR6-NEXT: seleqz $3, $2, $5 +; MIPS64ELR6-NEXT: srav $4, $2, $10 +; MIPS64ELR6-NEXT: seh $4, $4 +; MIPS64ELR6-NEXT: or $1, $zero, $4 +; MIPS64ELR6-NEXT: sllv $4, $4, $10 +; MIPS64ELR6-NEXT: slt $5, $4, $7 +; MIPS64ELR6-NEXT: seleqz $3, $4, $5 ; MIPS64ELR6-NEXT: selnez $5, $7, $5 ; MIPS64ELR6-NEXT: or $3, $3, $5 ; MIPS64ELR6-NEXT: and $3, $3, $8 @@ -1417,10 +1417,9 @@ define i16 @test_max_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS64ELR6-NEXT: or $4, $4, $3 ; MIPS64ELR6-NEXT: sc $4, 0($6) ; MIPS64ELR6-NEXT: beqzc $4, .LBB4_1 +; MIPS64ELR6-NEXT: nop ; MIPS64ELR6-NEXT: # %bb.2: # %entry -; MIPS64ELR6-NEXT: and $1, $2, $8 -; MIPS64ELR6-NEXT: srlv $1, $1, $10 -; MIPS64ELR6-NEXT: seh $1, $1 +; MIPS64ELR6-NEXT: .insn ; MIPS64ELR6-NEXT: # %bb.3: # %entry ; MIPS64ELR6-NEXT: sw $1, 12($sp) # 4-byte Folded Spill ; MIPS64ELR6-NEXT: # %bb.4: # %entry @@ -1428,6 +1427,7 @@ define i16 @test_max_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS64ELR6-NEXT: sync ; MIPS64ELR6-NEXT: daddiu $sp, $sp, 16 ; MIPS64ELR6-NEXT: jrc $ra + entry: %0 = atomicrmw max ptr %ptr, i16 %val seq_cst ret i16 %0 @@ -1452,8 +1452,12 @@ define i16 @test_min_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS-NEXT: $BB5_1: # %entry ; MIPS-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPS-NEXT: ll $2, 0($6) -; MIPS-NEXT: slt $5, $2, $7 -; MIPS-NEXT: move $3, $2 +; MIPS-NEXT: srav $4, $2, $10 +; MIPS-NEXT: seh $4, $4 +; MIPS-NEXT: or $1, $zero, $4 +; MIPS-NEXT: sllv $4, $4, $10 +; MIPS-NEXT: slt $5, $4, $7 +; MIPS-NEXT: move $3, $4 ; MIPS-NEXT: movz $3, $7, $5 ; MIPS-NEXT: and $3, $3, $8 ; MIPS-NEXT: and $4, $2, $9 @@ -1462,9 +1466,7 @@ define i16 @test_min_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS-NEXT: beqz $4, $BB5_1 ; MIPS-NEXT: nop ; MIPS-NEXT: # %bb.2: # %entry -; MIPS-NEXT: and $1, $2, $8 -; MIPS-NEXT: srlv $1, $1, $10 -; MIPS-NEXT: seh $1, $1 +; MIPS-NEXT: .insn ; MIPS-NEXT: # %bb.3: # %entry ; MIPS-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MIPS-NEXT: # %bb.4: # %entry @@ -1492,8 +1494,12 @@ define i16 @test_min_16(ptr nocapture %ptr, i16 signext %val) { ; MIPSR6-NEXT: $BB5_1: # %entry ; MIPSR6-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPSR6-NEXT: ll $2, 0($6) -; MIPSR6-NEXT: slt $5, $2, $7 -; MIPSR6-NEXT: selnez $3, $2, $5 +; MIPSR6-NEXT: srav $4, $2, $10 +; MIPSR6-NEXT: seh $4, $4 +; MIPSR6-NEXT: or $1, $zero, $4 +; MIPSR6-NEXT: sllv $4, $4, $10 +; MIPSR6-NEXT: slt $5, $4, $7 +; MIPSR6-NEXT: selnez $3, $4, $5 ; MIPSR6-NEXT: seleqz $5, $7, $5 ; MIPSR6-NEXT: or $3, $3, $5 ; MIPSR6-NEXT: and $3, $3, $8 @@ -1501,10 +1507,9 @@ define i16 @test_min_16(ptr nocapture %ptr, i16 signext %val) { ; MIPSR6-NEXT: or $4, $4, $3 ; MIPSR6-NEXT: sc $4, 0($6) ; MIPSR6-NEXT: beqzc $4, $BB5_1 +; MIPSR6-NEXT: nop ; MIPSR6-NEXT: # %bb.2: # %entry -; MIPSR6-NEXT: and $1, $2, $8 -; MIPSR6-NEXT: srlv $1, $1, $10 -; MIPSR6-NEXT: seh $1, $1 +; MIPSR6-NEXT: .insn ; MIPSR6-NEXT: # %bb.3: # %entry ; MIPSR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MIPSR6-NEXT: # %bb.4: # %entry @@ -1531,8 +1536,12 @@ define i16 @test_min_16(ptr nocapture %ptr, i16 signext %val) { ; MM-NEXT: $BB5_1: # %entry ; MM-NEXT: # =>This Inner Loop Header: Depth=1 ; MM-NEXT: ll $2, 0($6) -; MM-NEXT: slt $5, $2, $7 -; MM-NEXT: or $3, $2, $zero +; MM-NEXT: srav $4, $2, $10 +; MM-NEXT: seh $4, $4 +; MM-NEXT: or $1, $zero, $4 +; MM-NEXT: sllv $4, $4, $10 +; MM-NEXT: slt $5, $4, $7 +; MM-NEXT: or $3, $4, $zero ; MM-NEXT: movz $3, $7, $5 ; MM-NEXT: and $3, $3, $8 ; MM-NEXT: and $4, $2, $9 @@ -1540,9 +1549,7 @@ define i16 @test_min_16(ptr nocapture %ptr, i16 signext %val) { ; MM-NEXT: sc $4, 0($6) ; MM-NEXT: beqzc $4, $BB5_1 ; MM-NEXT: # %bb.2: # %entry -; MM-NEXT: and $1, $2, $8 -; MM-NEXT: srlv $1, $1, $10 -; MM-NEXT: seh $1, $1 +; MM-NEXT: .insn ; MM-NEXT: # %bb.3: # %entry ; MM-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MM-NEXT: # %bb.4: # %entry @@ -1569,8 +1576,12 @@ define i16 @test_min_16(ptr nocapture %ptr, i16 signext %val) { ; MMR6-NEXT: $BB5_1: # %entry ; MMR6-NEXT: # =>This Inner Loop Header: Depth=1 ; MMR6-NEXT: ll $2, 0($6) -; MMR6-NEXT: slt $5, $2, $7 -; MMR6-NEXT: selnez $3, $2, $5 +; MMR6-NEXT: srav $4, $2, $10 +; MMR6-NEXT: seh $4, $4 +; MMR6-NEXT: or $1, $zero, $4 +; MMR6-NEXT: sllv $4, $4, $10 +; MMR6-NEXT: slt $5, $4, $7 +; MMR6-NEXT: selnez $3, $4, $5 ; MMR6-NEXT: seleqz $5, $7, $5 ; MMR6-NEXT: or $3, $3, $5 ; MMR6-NEXT: and $3, $3, $8 @@ -1579,9 +1590,7 @@ define i16 @test_min_16(ptr nocapture %ptr, i16 signext %val) { ; MMR6-NEXT: sc $4, 0($6) ; MMR6-NEXT: beqc $4, $zero, $BB5_1 ; MMR6-NEXT: # %bb.2: # %entry -; MMR6-NEXT: and $1, $2, $8 -; MMR6-NEXT: srlv $1, $1, $10 -; MMR6-NEXT: seh $1, $1 +; MMR6-NEXT: .insn ; MMR6-NEXT: # %bb.3: # %entry ; MMR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MMR6-NEXT: # %bb.4: # %entry @@ -1607,14 +1616,13 @@ define i16 @test_min_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS32-NEXT: $BB5_1: # %entry ; MIPS32-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPS32-NEXT: ll $2, 0($6) -; MIPS32-NEXT: srav $2, $2, $10 -; MIPS32-NEXT: srav $7, $7, $10 -; MIPS32-NEXT: sll $2, $2, 16 -; MIPS32-NEXT: sra $2, $2, 16 -; MIPS32-NEXT: sll $7, $7, 16 -; MIPS32-NEXT: sra $7, $7, 16 -; MIPS32-NEXT: slt $5, $2, $7 -; MIPS32-NEXT: move $3, $2 +; MIPS32-NEXT: srav $4, $2, $10 +; MIPS32-NEXT: sll $4, $4, 16 +; MIPS32-NEXT: sra $4, $4, 16 +; MIPS32-NEXT: or $1, $zero, $4 +; MIPS32-NEXT: sllv $4, $4, $10 +; MIPS32-NEXT: slt $5, $4, $7 +; MIPS32-NEXT: move $3, $4 ; MIPS32-NEXT: movz $3, $7, $5 ; MIPS32-NEXT: and $3, $3, $8 ; MIPS32-NEXT: and $4, $2, $9 @@ -1623,10 +1631,7 @@ define i16 @test_min_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS32-NEXT: beqz $4, $BB5_1 ; MIPS32-NEXT: nop ; MIPS32-NEXT: # %bb.2: # %entry -; MIPS32-NEXT: and $1, $2, $8 -; MIPS32-NEXT: srlv $1, $1, $10 -; MIPS32-NEXT: sll $1, $1, 16 -; MIPS32-NEXT: sra $1, $1, 16 +; MIPS32-NEXT: .insn ; MIPS32-NEXT: # %bb.3: # %entry ; MIPS32-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MIPS32-NEXT: # %bb.4: # %entry @@ -1653,12 +1658,12 @@ define i16 @test_min_16(ptr nocapture %ptr, i16 signext %val) { ; MIPSEL-NEXT: $BB5_1: # %entry ; MIPSEL-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPSEL-NEXT: ll $2, 0($6) -; MIPSEL-NEXT: srav $2, $2, $10 -; MIPSEL-NEXT: srav $7, $7, $10 -; MIPSEL-NEXT: seh $2, $2 -; MIPSEL-NEXT: seh $7, $7 -; MIPSEL-NEXT: slt $5, $2, $7 -; MIPSEL-NEXT: move $3, $2 +; MIPSEL-NEXT: srav $4, $2, $10 +; MIPSEL-NEXT: seh $4, $4 +; MIPSEL-NEXT: or $1, $zero, $4 +; MIPSEL-NEXT: sllv $4, $4, $10 +; MIPSEL-NEXT: slt $5, $4, $7 +; MIPSEL-NEXT: move $3, $4 ; MIPSEL-NEXT: movz $3, $7, $5 ; MIPSEL-NEXT: and $3, $3, $8 ; MIPSEL-NEXT: and $4, $2, $9 @@ -1667,9 +1672,7 @@ define i16 @test_min_16(ptr nocapture %ptr, i16 signext %val) { ; MIPSEL-NEXT: beqz $4, $BB5_1 ; MIPSEL-NEXT: nop ; MIPSEL-NEXT: # %bb.2: # %entry -; MIPSEL-NEXT: and $1, $2, $8 -; MIPSEL-NEXT: srlv $1, $1, $10 -; MIPSEL-NEXT: seh $1, $1 +; MIPSEL-NEXT: .insn ; MIPSEL-NEXT: # %bb.3: # %entry ; MIPSEL-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MIPSEL-NEXT: # %bb.4: # %entry @@ -1696,12 +1699,12 @@ define i16 @test_min_16(ptr nocapture %ptr, i16 signext %val) { ; MIPSELR6-NEXT: $BB5_1: # %entry ; MIPSELR6-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPSELR6-NEXT: ll $2, 0($6) -; MIPSELR6-NEXT: srav $2, $2, $10 -; MIPSELR6-NEXT: srav $7, $7, $10 -; MIPSELR6-NEXT: seh $2, $2 -; MIPSELR6-NEXT: seh $7, $7 -; MIPSELR6-NEXT: slt $5, $2, $7 -; MIPSELR6-NEXT: selnez $3, $2, $5 +; MIPSELR6-NEXT: srav $4, $2, $10 +; MIPSELR6-NEXT: seh $4, $4 +; MIPSELR6-NEXT: or $1, $zero, $4 +; MIPSELR6-NEXT: sllv $4, $4, $10 +; MIPSELR6-NEXT: slt $5, $4, $7 +; MIPSELR6-NEXT: selnez $3, $4, $5 ; MIPSELR6-NEXT: seleqz $5, $7, $5 ; MIPSELR6-NEXT: or $3, $3, $5 ; MIPSELR6-NEXT: and $3, $3, $8 @@ -1709,10 +1712,9 @@ define i16 @test_min_16(ptr nocapture %ptr, i16 signext %val) { ; MIPSELR6-NEXT: or $4, $4, $3 ; MIPSELR6-NEXT: sc $4, 0($6) ; MIPSELR6-NEXT: beqzc $4, $BB5_1 +; MIPSELR6-NEXT: nop ; MIPSELR6-NEXT: # %bb.2: # %entry -; MIPSELR6-NEXT: and $1, $2, $8 -; MIPSELR6-NEXT: srlv $1, $1, $10 -; MIPSELR6-NEXT: seh $1, $1 +; MIPSELR6-NEXT: .insn ; MIPSELR6-NEXT: # %bb.3: # %entry ; MIPSELR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MIPSELR6-NEXT: # %bb.4: # %entry @@ -1738,12 +1740,12 @@ define i16 @test_min_16(ptr nocapture %ptr, i16 signext %val) { ; MMEL-NEXT: $BB5_1: # %entry ; MMEL-NEXT: # =>This Inner Loop Header: Depth=1 ; MMEL-NEXT: ll $2, 0($6) -; MMEL-NEXT: srav $2, $2, $10 -; MMEL-NEXT: srav $7, $7, $10 -; MMEL-NEXT: seh $2, $2 -; MMEL-NEXT: seh $7, $7 -; MMEL-NEXT: slt $5, $2, $7 -; MMEL-NEXT: or $3, $2, $zero +; MMEL-NEXT: srav $4, $2, $10 +; MMEL-NEXT: seh $4, $4 +; MMEL-NEXT: or $1, $zero, $4 +; MMEL-NEXT: sllv $4, $4, $10 +; MMEL-NEXT: slt $5, $4, $7 +; MMEL-NEXT: or $3, $4, $zero ; MMEL-NEXT: movz $3, $7, $5 ; MMEL-NEXT: and $3, $3, $8 ; MMEL-NEXT: and $4, $2, $9 @@ -1751,9 +1753,7 @@ define i16 @test_min_16(ptr nocapture %ptr, i16 signext %val) { ; MMEL-NEXT: sc $4, 0($6) ; MMEL-NEXT: beqzc $4, $BB5_1 ; MMEL-NEXT: # %bb.2: # %entry -; MMEL-NEXT: and $1, $2, $8 -; MMEL-NEXT: srlv $1, $1, $10 -; MMEL-NEXT: seh $1, $1 +; MMEL-NEXT: .insn ; MMEL-NEXT: # %bb.3: # %entry ; MMEL-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MMEL-NEXT: # %bb.4: # %entry @@ -1779,12 +1779,12 @@ define i16 @test_min_16(ptr nocapture %ptr, i16 signext %val) { ; MMELR6-NEXT: $BB5_1: # %entry ; MMELR6-NEXT: # =>This Inner Loop Header: Depth=1 ; MMELR6-NEXT: ll $2, 0($6) -; MMELR6-NEXT: srav $2, $2, $10 -; MMELR6-NEXT: srav $7, $7, $10 -; MMELR6-NEXT: seh $2, $2 -; MMELR6-NEXT: seh $7, $7 -; MMELR6-NEXT: slt $5, $2, $7 -; MMELR6-NEXT: selnez $3, $2, $5 +; MMELR6-NEXT: srav $4, $2, $10 +; MMELR6-NEXT: seh $4, $4 +; MMELR6-NEXT: or $1, $zero, $4 +; MMELR6-NEXT: sllv $4, $4, $10 +; MMELR6-NEXT: slt $5, $4, $7 +; MMELR6-NEXT: selnez $3, $4, $5 ; MMELR6-NEXT: seleqz $5, $7, $5 ; MMELR6-NEXT: or $3, $3, $5 ; MMELR6-NEXT: and $3, $3, $8 @@ -1793,9 +1793,7 @@ define i16 @test_min_16(ptr nocapture %ptr, i16 signext %val) { ; MMELR6-NEXT: sc $4, 0($6) ; MMELR6-NEXT: beqc $4, $zero, $BB5_1 ; MMELR6-NEXT: # %bb.2: # %entry -; MMELR6-NEXT: and $1, $2, $8 -; MMELR6-NEXT: srlv $1, $1, $10 -; MMELR6-NEXT: seh $1, $1 +; MMELR6-NEXT: .insn ; MMELR6-NEXT: # %bb.3: # %entry ; MMELR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MMELR6-NEXT: # %bb.4: # %entry @@ -1822,8 +1820,12 @@ define i16 @test_min_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS64-NEXT: .LBB5_1: # %entry ; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPS64-NEXT: ll $2, 0($6) -; MIPS64-NEXT: slt $5, $2, $7 -; MIPS64-NEXT: move $3, $2 +; MIPS64-NEXT: srav $4, $2, $10 +; MIPS64-NEXT: seh $4, $4 +; MIPS64-NEXT: or $1, $zero, $4 +; MIPS64-NEXT: sllv $4, $4, $10 +; MIPS64-NEXT: slt $5, $4, $7 +; MIPS64-NEXT: move $3, $4 ; MIPS64-NEXT: movz $3, $7, $5 ; MIPS64-NEXT: and $3, $3, $8 ; MIPS64-NEXT: and $4, $2, $9 @@ -1832,9 +1834,7 @@ define i16 @test_min_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS64-NEXT: beqz $4, .LBB5_1 ; MIPS64-NEXT: nop ; MIPS64-NEXT: # %bb.2: # %entry -; MIPS64-NEXT: and $1, $2, $8 -; MIPS64-NEXT: srlv $1, $1, $10 -; MIPS64-NEXT: seh $1, $1 +; MIPS64-NEXT: .insn ; MIPS64-NEXT: # %bb.3: # %entry ; MIPS64-NEXT: sw $1, 12($sp) # 4-byte Folded Spill ; MIPS64-NEXT: # %bb.4: # %entry @@ -1862,8 +1862,12 @@ define i16 @test_min_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS64R6-NEXT: .LBB5_1: # %entry ; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPS64R6-NEXT: ll $2, 0($6) -; MIPS64R6-NEXT: slt $5, $2, $7 -; MIPS64R6-NEXT: selnez $3, $2, $5 +; MIPS64R6-NEXT: srav $4, $2, $10 +; MIPS64R6-NEXT: seh $4, $4 +; MIPS64R6-NEXT: or $1, $zero, $4 +; MIPS64R6-NEXT: sllv $4, $4, $10 +; MIPS64R6-NEXT: slt $5, $4, $7 +; MIPS64R6-NEXT: selnez $3, $4, $5 ; MIPS64R6-NEXT: seleqz $5, $7, $5 ; MIPS64R6-NEXT: or $3, $3, $5 ; MIPS64R6-NEXT: and $3, $3, $8 @@ -1871,10 +1875,9 @@ define i16 @test_min_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS64R6-NEXT: or $4, $4, $3 ; MIPS64R6-NEXT: sc $4, 0($6) ; MIPS64R6-NEXT: beqzc $4, .LBB5_1 +; MIPS64R6-NEXT: nop ; MIPS64R6-NEXT: # %bb.2: # %entry -; MIPS64R6-NEXT: and $1, $2, $8 -; MIPS64R6-NEXT: srlv $1, $1, $10 -; MIPS64R6-NEXT: seh $1, $1 +; MIPS64R6-NEXT: .insn ; MIPS64R6-NEXT: # %bb.3: # %entry ; MIPS64R6-NEXT: sw $1, 12($sp) # 4-byte Folded Spill ; MIPS64R6-NEXT: # %bb.4: # %entry @@ -1900,12 +1903,12 @@ define i16 @test_min_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS64EL-NEXT: .LBB5_1: # %entry ; MIPS64EL-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPS64EL-NEXT: ll $2, 0($6) -; MIPS64EL-NEXT: srav $2, $2, $10 -; MIPS64EL-NEXT: srav $7, $7, $10 -; MIPS64EL-NEXT: seh $2, $2 -; MIPS64EL-NEXT: seh $7, $7 -; MIPS64EL-NEXT: slt $5, $2, $7 -; MIPS64EL-NEXT: move $3, $2 +; MIPS64EL-NEXT: srav $4, $2, $10 +; MIPS64EL-NEXT: seh $4, $4 +; MIPS64EL-NEXT: or $1, $zero, $4 +; MIPS64EL-NEXT: sllv $4, $4, $10 +; MIPS64EL-NEXT: slt $5, $4, $7 +; MIPS64EL-NEXT: move $3, $4 ; MIPS64EL-NEXT: movz $3, $7, $5 ; MIPS64EL-NEXT: and $3, $3, $8 ; MIPS64EL-NEXT: and $4, $2, $9 @@ -1914,9 +1917,7 @@ define i16 @test_min_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS64EL-NEXT: beqz $4, .LBB5_1 ; MIPS64EL-NEXT: nop ; MIPS64EL-NEXT: # %bb.2: # %entry -; MIPS64EL-NEXT: and $1, $2, $8 -; MIPS64EL-NEXT: srlv $1, $1, $10 -; MIPS64EL-NEXT: seh $1, $1 +; MIPS64EL-NEXT: .insn ; MIPS64EL-NEXT: # %bb.3: # %entry ; MIPS64EL-NEXT: sw $1, 12($sp) # 4-byte Folded Spill ; MIPS64EL-NEXT: # %bb.4: # %entry @@ -1943,12 +1944,12 @@ define i16 @test_min_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS64ELR6-NEXT: .LBB5_1: # %entry ; MIPS64ELR6-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPS64ELR6-NEXT: ll $2, 0($6) -; MIPS64ELR6-NEXT: srav $2, $2, $10 -; MIPS64ELR6-NEXT: srav $7, $7, $10 -; MIPS64ELR6-NEXT: seh $2, $2 -; MIPS64ELR6-NEXT: seh $7, $7 -; MIPS64ELR6-NEXT: slt $5, $2, $7 -; MIPS64ELR6-NEXT: selnez $3, $2, $5 +; MIPS64ELR6-NEXT: srav $4, $2, $10 +; MIPS64ELR6-NEXT: seh $4, $4 +; MIPS64ELR6-NEXT: or $1, $zero, $4 +; MIPS64ELR6-NEXT: sllv $4, $4, $10 +; MIPS64ELR6-NEXT: slt $5, $4, $7 +; MIPS64ELR6-NEXT: selnez $3, $4, $5 ; MIPS64ELR6-NEXT: seleqz $5, $7, $5 ; MIPS64ELR6-NEXT: or $3, $3, $5 ; MIPS64ELR6-NEXT: and $3, $3, $8 @@ -1956,10 +1957,9 @@ define i16 @test_min_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS64ELR6-NEXT: or $4, $4, $3 ; MIPS64ELR6-NEXT: sc $4, 0($6) ; MIPS64ELR6-NEXT: beqzc $4, .LBB5_1 +; MIPS64ELR6-NEXT: nop ; MIPS64ELR6-NEXT: # %bb.2: # %entry -; MIPS64ELR6-NEXT: and $1, $2, $8 -; MIPS64ELR6-NEXT: srlv $1, $1, $10 -; MIPS64ELR6-NEXT: seh $1, $1 +; MIPS64ELR6-NEXT: .insn ; MIPS64ELR6-NEXT: # %bb.3: # %entry ; MIPS64ELR6-NEXT: sw $1, 12($sp) # 4-byte Folded Spill ; MIPS64ELR6-NEXT: # %bb.4: # %entry @@ -1991,8 +1991,12 @@ define i16 @test_umax_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS-NEXT: $BB6_1: # %entry ; MIPS-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPS-NEXT: ll $2, 0($6) -; MIPS-NEXT: sltu $5, $2, $7 -; MIPS-NEXT: move $3, $2 +; MIPS-NEXT: srav $4, $2, $10 +; MIPS-NEXT: andi $4, $4, 65535 +; MIPS-NEXT: or $1, $zero, $4 +; MIPS-NEXT: sllv $4, $4, $10 +; MIPS-NEXT: sltu $5, $4, $7 +; MIPS-NEXT: move $3, $4 ; MIPS-NEXT: movn $3, $7, $5 ; MIPS-NEXT: and $3, $3, $8 ; MIPS-NEXT: and $4, $2, $9 @@ -2001,9 +2005,7 @@ define i16 @test_umax_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS-NEXT: beqz $4, $BB6_1 ; MIPS-NEXT: nop ; MIPS-NEXT: # %bb.2: # %entry -; MIPS-NEXT: and $1, $2, $8 -; MIPS-NEXT: srlv $1, $1, $10 -; MIPS-NEXT: seh $1, $1 +; MIPS-NEXT: .insn ; MIPS-NEXT: # %bb.3: # %entry ; MIPS-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MIPS-NEXT: # %bb.4: # %entry @@ -2031,8 +2033,12 @@ define i16 @test_umax_16(ptr nocapture %ptr, i16 signext %val) { ; MIPSR6-NEXT: $BB6_1: # %entry ; MIPSR6-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPSR6-NEXT: ll $2, 0($6) -; MIPSR6-NEXT: sltu $5, $2, $7 -; MIPSR6-NEXT: seleqz $3, $2, $5 +; MIPSR6-NEXT: srav $4, $2, $10 +; MIPSR6-NEXT: andi $4, $4, 65535 +; MIPSR6-NEXT: or $1, $zero, $4 +; MIPSR6-NEXT: sllv $4, $4, $10 +; MIPSR6-NEXT: sltu $5, $4, $7 +; MIPSR6-NEXT: seleqz $3, $4, $5 ; MIPSR6-NEXT: selnez $5, $7, $5 ; MIPSR6-NEXT: or $3, $3, $5 ; MIPSR6-NEXT: and $3, $3, $8 @@ -2040,10 +2046,9 @@ define i16 @test_umax_16(ptr nocapture %ptr, i16 signext %val) { ; MIPSR6-NEXT: or $4, $4, $3 ; MIPSR6-NEXT: sc $4, 0($6) ; MIPSR6-NEXT: beqzc $4, $BB6_1 +; MIPSR6-NEXT: nop ; MIPSR6-NEXT: # %bb.2: # %entry -; MIPSR6-NEXT: and $1, $2, $8 -; MIPSR6-NEXT: srlv $1, $1, $10 -; MIPSR6-NEXT: seh $1, $1 +; MIPSR6-NEXT: .insn ; MIPSR6-NEXT: # %bb.3: # %entry ; MIPSR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MIPSR6-NEXT: # %bb.4: # %entry @@ -2070,8 +2075,12 @@ define i16 @test_umax_16(ptr nocapture %ptr, i16 signext %val) { ; MM-NEXT: $BB6_1: # %entry ; MM-NEXT: # =>This Inner Loop Header: Depth=1 ; MM-NEXT: ll $2, 0($6) -; MM-NEXT: sltu $5, $2, $7 -; MM-NEXT: or $3, $2, $zero +; MM-NEXT: srav $4, $2, $10 +; MM-NEXT: andi $4, $4, 65535 +; MM-NEXT: or $1, $zero, $4 +; MM-NEXT: sllv $4, $4, $10 +; MM-NEXT: sltu $5, $4, $7 +; MM-NEXT: or $3, $4, $zero ; MM-NEXT: movn $3, $7, $5 ; MM-NEXT: and $3, $3, $8 ; MM-NEXT: and $4, $2, $9 @@ -2079,9 +2088,7 @@ define i16 @test_umax_16(ptr nocapture %ptr, i16 signext %val) { ; MM-NEXT: sc $4, 0($6) ; MM-NEXT: beqzc $4, $BB6_1 ; MM-NEXT: # %bb.2: # %entry -; MM-NEXT: and $1, $2, $8 -; MM-NEXT: srlv $1, $1, $10 -; MM-NEXT: seh $1, $1 +; MM-NEXT: .insn ; MM-NEXT: # %bb.3: # %entry ; MM-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MM-NEXT: # %bb.4: # %entry @@ -2108,8 +2115,12 @@ define i16 @test_umax_16(ptr nocapture %ptr, i16 signext %val) { ; MMR6-NEXT: $BB6_1: # %entry ; MMR6-NEXT: # =>This Inner Loop Header: Depth=1 ; MMR6-NEXT: ll $2, 0($6) -; MMR6-NEXT: sltu $5, $2, $7 -; MMR6-NEXT: seleqz $3, $2, $5 +; MMR6-NEXT: srav $4, $2, $10 +; MMR6-NEXT: andi $4, $4, 65535 +; MMR6-NEXT: or $1, $zero, $4 +; MMR6-NEXT: sllv $4, $4, $10 +; MMR6-NEXT: sltu $5, $4, $7 +; MMR6-NEXT: seleqz $3, $4, $5 ; MMR6-NEXT: selnez $5, $7, $5 ; MMR6-NEXT: or $3, $3, $5 ; MMR6-NEXT: and $3, $3, $8 @@ -2118,9 +2129,7 @@ define i16 @test_umax_16(ptr nocapture %ptr, i16 signext %val) { ; MMR6-NEXT: sc $4, 0($6) ; MMR6-NEXT: beqc $4, $zero, $BB6_1 ; MMR6-NEXT: # %bb.2: # %entry -; MMR6-NEXT: and $1, $2, $8 -; MMR6-NEXT: srlv $1, $1, $10 -; MMR6-NEXT: seh $1, $1 +; MMR6-NEXT: .insn ; MMR6-NEXT: # %bb.3: # %entry ; MMR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MMR6-NEXT: # %bb.4: # %entry @@ -2146,10 +2155,13 @@ define i16 @test_umax_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS32-NEXT: $BB6_1: # %entry ; MIPS32-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPS32-NEXT: ll $2, 0($6) -; MIPS32-NEXT: and $2, $2, $8 -; MIPS32-NEXT: and $7, $7, $8 -; MIPS32-NEXT: sltu $5, $2, $7 -; MIPS32-NEXT: move $3, $2 +; MIPS32-NEXT: srav $4, $2, $10 +; MIPS32-NEXT: sll $4, $4, 16 +; MIPS32-NEXT: srl $4, $4, 16 +; MIPS32-NEXT: or $1, $zero, $4 +; MIPS32-NEXT: sllv $4, $4, $10 +; MIPS32-NEXT: sltu $5, $4, $7 +; MIPS32-NEXT: move $3, $4 ; MIPS32-NEXT: movn $3, $7, $5 ; MIPS32-NEXT: and $3, $3, $8 ; MIPS32-NEXT: and $4, $2, $9 @@ -2158,10 +2170,7 @@ define i16 @test_umax_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS32-NEXT: beqz $4, $BB6_1 ; MIPS32-NEXT: nop ; MIPS32-NEXT: # %bb.2: # %entry -; MIPS32-NEXT: and $1, $2, $8 -; MIPS32-NEXT: srlv $1, $1, $10 -; MIPS32-NEXT: sll $1, $1, 16 -; MIPS32-NEXT: sra $1, $1, 16 +; MIPS32-NEXT: .insn ; MIPS32-NEXT: # %bb.3: # %entry ; MIPS32-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MIPS32-NEXT: # %bb.4: # %entry @@ -2188,10 +2197,12 @@ define i16 @test_umax_16(ptr nocapture %ptr, i16 signext %val) { ; MIPSEL-NEXT: $BB6_1: # %entry ; MIPSEL-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPSEL-NEXT: ll $2, 0($6) -; MIPSEL-NEXT: and $2, $2, $8 -; MIPSEL-NEXT: and $7, $7, $8 -; MIPSEL-NEXT: sltu $5, $2, $7 -; MIPSEL-NEXT: move $3, $2 +; MIPSEL-NEXT: srav $4, $2, $10 +; MIPSEL-NEXT: andi $4, $4, 65535 +; MIPSEL-NEXT: or $1, $zero, $4 +; MIPSEL-NEXT: sllv $4, $4, $10 +; MIPSEL-NEXT: sltu $5, $4, $7 +; MIPSEL-NEXT: move $3, $4 ; MIPSEL-NEXT: movn $3, $7, $5 ; MIPSEL-NEXT: and $3, $3, $8 ; MIPSEL-NEXT: and $4, $2, $9 @@ -2200,9 +2211,7 @@ define i16 @test_umax_16(ptr nocapture %ptr, i16 signext %val) { ; MIPSEL-NEXT: beqz $4, $BB6_1 ; MIPSEL-NEXT: nop ; MIPSEL-NEXT: # %bb.2: # %entry -; MIPSEL-NEXT: and $1, $2, $8 -; MIPSEL-NEXT: srlv $1, $1, $10 -; MIPSEL-NEXT: seh $1, $1 +; MIPSEL-NEXT: .insn ; MIPSEL-NEXT: # %bb.3: # %entry ; MIPSEL-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MIPSEL-NEXT: # %bb.4: # %entry @@ -2229,10 +2238,12 @@ define i16 @test_umax_16(ptr nocapture %ptr, i16 signext %val) { ; MIPSELR6-NEXT: $BB6_1: # %entry ; MIPSELR6-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPSELR6-NEXT: ll $2, 0($6) -; MIPSELR6-NEXT: and $2, $2, $8 -; MIPSELR6-NEXT: and $7, $7, $8 -; MIPSELR6-NEXT: sltu $5, $2, $7 -; MIPSELR6-NEXT: seleqz $3, $2, $5 +; MIPSELR6-NEXT: srav $4, $2, $10 +; MIPSELR6-NEXT: andi $4, $4, 65535 +; MIPSELR6-NEXT: or $1, $zero, $4 +; MIPSELR6-NEXT: sllv $4, $4, $10 +; MIPSELR6-NEXT: sltu $5, $4, $7 +; MIPSELR6-NEXT: seleqz $3, $4, $5 ; MIPSELR6-NEXT: selnez $5, $7, $5 ; MIPSELR6-NEXT: or $3, $3, $5 ; MIPSELR6-NEXT: and $3, $3, $8 @@ -2240,10 +2251,9 @@ define i16 @test_umax_16(ptr nocapture %ptr, i16 signext %val) { ; MIPSELR6-NEXT: or $4, $4, $3 ; MIPSELR6-NEXT: sc $4, 0($6) ; MIPSELR6-NEXT: beqzc $4, $BB6_1 +; MIPSELR6-NEXT: nop ; MIPSELR6-NEXT: # %bb.2: # %entry -; MIPSELR6-NEXT: and $1, $2, $8 -; MIPSELR6-NEXT: srlv $1, $1, $10 -; MIPSELR6-NEXT: seh $1, $1 +; MIPSELR6-NEXT: .insn ; MIPSELR6-NEXT: # %bb.3: # %entry ; MIPSELR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MIPSELR6-NEXT: # %bb.4: # %entry @@ -2269,10 +2279,12 @@ define i16 @test_umax_16(ptr nocapture %ptr, i16 signext %val) { ; MMEL-NEXT: $BB6_1: # %entry ; MMEL-NEXT: # =>This Inner Loop Header: Depth=1 ; MMEL-NEXT: ll $2, 0($6) -; MMEL-NEXT: and $2, $2, $8 -; MMEL-NEXT: and $7, $7, $8 -; MMEL-NEXT: sltu $5, $2, $7 -; MMEL-NEXT: or $3, $2, $zero +; MMEL-NEXT: srav $4, $2, $10 +; MMEL-NEXT: andi $4, $4, 65535 +; MMEL-NEXT: or $1, $zero, $4 +; MMEL-NEXT: sllv $4, $4, $10 +; MMEL-NEXT: sltu $5, $4, $7 +; MMEL-NEXT: or $3, $4, $zero ; MMEL-NEXT: movn $3, $7, $5 ; MMEL-NEXT: and $3, $3, $8 ; MMEL-NEXT: and $4, $2, $9 @@ -2280,9 +2292,7 @@ define i16 @test_umax_16(ptr nocapture %ptr, i16 signext %val) { ; MMEL-NEXT: sc $4, 0($6) ; MMEL-NEXT: beqzc $4, $BB6_1 ; MMEL-NEXT: # %bb.2: # %entry -; MMEL-NEXT: and $1, $2, $8 -; MMEL-NEXT: srlv $1, $1, $10 -; MMEL-NEXT: seh $1, $1 +; MMEL-NEXT: .insn ; MMEL-NEXT: # %bb.3: # %entry ; MMEL-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MMEL-NEXT: # %bb.4: # %entry @@ -2308,10 +2318,12 @@ define i16 @test_umax_16(ptr nocapture %ptr, i16 signext %val) { ; MMELR6-NEXT: $BB6_1: # %entry ; MMELR6-NEXT: # =>This Inner Loop Header: Depth=1 ; MMELR6-NEXT: ll $2, 0($6) -; MMELR6-NEXT: and $2, $2, $8 -; MMELR6-NEXT: and $7, $7, $8 -; MMELR6-NEXT: sltu $5, $2, $7 -; MMELR6-NEXT: seleqz $3, $2, $5 +; MMELR6-NEXT: srav $4, $2, $10 +; MMELR6-NEXT: andi $4, $4, 65535 +; MMELR6-NEXT: or $1, $zero, $4 +; MMELR6-NEXT: sllv $4, $4, $10 +; MMELR6-NEXT: sltu $5, $4, $7 +; MMELR6-NEXT: seleqz $3, $4, $5 ; MMELR6-NEXT: selnez $5, $7, $5 ; MMELR6-NEXT: or $3, $3, $5 ; MMELR6-NEXT: and $3, $3, $8 @@ -2320,9 +2332,7 @@ define i16 @test_umax_16(ptr nocapture %ptr, i16 signext %val) { ; MMELR6-NEXT: sc $4, 0($6) ; MMELR6-NEXT: beqc $4, $zero, $BB6_1 ; MMELR6-NEXT: # %bb.2: # %entry -; MMELR6-NEXT: and $1, $2, $8 -; MMELR6-NEXT: srlv $1, $1, $10 -; MMELR6-NEXT: seh $1, $1 +; MMELR6-NEXT: .insn ; MMELR6-NEXT: # %bb.3: # %entry ; MMELR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MMELR6-NEXT: # %bb.4: # %entry @@ -2349,8 +2359,12 @@ define i16 @test_umax_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS64-NEXT: .LBB6_1: # %entry ; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPS64-NEXT: ll $2, 0($6) -; MIPS64-NEXT: sltu $5, $2, $7 -; MIPS64-NEXT: move $3, $2 +; MIPS64-NEXT: srav $4, $2, $10 +; MIPS64-NEXT: andi $4, $4, 65535 +; MIPS64-NEXT: or $1, $zero, $4 +; MIPS64-NEXT: sllv $4, $4, $10 +; MIPS64-NEXT: sltu $5, $4, $7 +; MIPS64-NEXT: move $3, $4 ; MIPS64-NEXT: movn $3, $7, $5 ; MIPS64-NEXT: and $3, $3, $8 ; MIPS64-NEXT: and $4, $2, $9 @@ -2359,9 +2373,7 @@ define i16 @test_umax_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS64-NEXT: beqz $4, .LBB6_1 ; MIPS64-NEXT: nop ; MIPS64-NEXT: # %bb.2: # %entry -; MIPS64-NEXT: and $1, $2, $8 -; MIPS64-NEXT: srlv $1, $1, $10 -; MIPS64-NEXT: seh $1, $1 +; MIPS64-NEXT: .insn ; MIPS64-NEXT: # %bb.3: # %entry ; MIPS64-NEXT: sw $1, 12($sp) # 4-byte Folded Spill ; MIPS64-NEXT: # %bb.4: # %entry @@ -2389,8 +2401,12 @@ define i16 @test_umax_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS64R6-NEXT: .LBB6_1: # %entry ; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPS64R6-NEXT: ll $2, 0($6) -; MIPS64R6-NEXT: sltu $5, $2, $7 -; MIPS64R6-NEXT: seleqz $3, $2, $5 +; MIPS64R6-NEXT: srav $4, $2, $10 +; MIPS64R6-NEXT: andi $4, $4, 65535 +; MIPS64R6-NEXT: or $1, $zero, $4 +; MIPS64R6-NEXT: sllv $4, $4, $10 +; MIPS64R6-NEXT: sltu $5, $4, $7 +; MIPS64R6-NEXT: seleqz $3, $4, $5 ; MIPS64R6-NEXT: selnez $5, $7, $5 ; MIPS64R6-NEXT: or $3, $3, $5 ; MIPS64R6-NEXT: and $3, $3, $8 @@ -2398,10 +2414,9 @@ define i16 @test_umax_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS64R6-NEXT: or $4, $4, $3 ; MIPS64R6-NEXT: sc $4, 0($6) ; MIPS64R6-NEXT: beqzc $4, .LBB6_1 +; MIPS64R6-NEXT: nop ; MIPS64R6-NEXT: # %bb.2: # %entry -; MIPS64R6-NEXT: and $1, $2, $8 -; MIPS64R6-NEXT: srlv $1, $1, $10 -; MIPS64R6-NEXT: seh $1, $1 +; MIPS64R6-NEXT: .insn ; MIPS64R6-NEXT: # %bb.3: # %entry ; MIPS64R6-NEXT: sw $1, 12($sp) # 4-byte Folded Spill ; MIPS64R6-NEXT: # %bb.4: # %entry @@ -2427,10 +2442,12 @@ define i16 @test_umax_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS64EL-NEXT: .LBB6_1: # %entry ; MIPS64EL-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPS64EL-NEXT: ll $2, 0($6) -; MIPS64EL-NEXT: and $2, $2, $8 -; MIPS64EL-NEXT: and $7, $7, $8 -; MIPS64EL-NEXT: sltu $5, $2, $7 -; MIPS64EL-NEXT: move $3, $2 +; MIPS64EL-NEXT: srav $4, $2, $10 +; MIPS64EL-NEXT: andi $4, $4, 65535 +; MIPS64EL-NEXT: or $1, $zero, $4 +; MIPS64EL-NEXT: sllv $4, $4, $10 +; MIPS64EL-NEXT: sltu $5, $4, $7 +; MIPS64EL-NEXT: move $3, $4 ; MIPS64EL-NEXT: movn $3, $7, $5 ; MIPS64EL-NEXT: and $3, $3, $8 ; MIPS64EL-NEXT: and $4, $2, $9 @@ -2439,9 +2456,7 @@ define i16 @test_umax_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS64EL-NEXT: beqz $4, .LBB6_1 ; MIPS64EL-NEXT: nop ; MIPS64EL-NEXT: # %bb.2: # %entry -; MIPS64EL-NEXT: and $1, $2, $8 -; MIPS64EL-NEXT: srlv $1, $1, $10 -; MIPS64EL-NEXT: seh $1, $1 +; MIPS64EL-NEXT: .insn ; MIPS64EL-NEXT: # %bb.3: # %entry ; MIPS64EL-NEXT: sw $1, 12($sp) # 4-byte Folded Spill ; MIPS64EL-NEXT: # %bb.4: # %entry @@ -2468,10 +2483,12 @@ define i16 @test_umax_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS64ELR6-NEXT: .LBB6_1: # %entry ; MIPS64ELR6-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPS64ELR6-NEXT: ll $2, 0($6) -; MIPS64ELR6-NEXT: and $2, $2, $8 -; MIPS64ELR6-NEXT: and $7, $7, $8 -; MIPS64ELR6-NEXT: sltu $5, $2, $7 -; MIPS64ELR6-NEXT: seleqz $3, $2, $5 +; MIPS64ELR6-NEXT: srav $4, $2, $10 +; MIPS64ELR6-NEXT: andi $4, $4, 65535 +; MIPS64ELR6-NEXT: or $1, $zero, $4 +; MIPS64ELR6-NEXT: sllv $4, $4, $10 +; MIPS64ELR6-NEXT: sltu $5, $4, $7 +; MIPS64ELR6-NEXT: seleqz $3, $4, $5 ; MIPS64ELR6-NEXT: selnez $5, $7, $5 ; MIPS64ELR6-NEXT: or $3, $3, $5 ; MIPS64ELR6-NEXT: and $3, $3, $8 @@ -2479,10 +2496,9 @@ define i16 @test_umax_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS64ELR6-NEXT: or $4, $4, $3 ; MIPS64ELR6-NEXT: sc $4, 0($6) ; MIPS64ELR6-NEXT: beqzc $4, .LBB6_1 +; MIPS64ELR6-NEXT: nop ; MIPS64ELR6-NEXT: # %bb.2: # %entry -; MIPS64ELR6-NEXT: and $1, $2, $8 -; MIPS64ELR6-NEXT: srlv $1, $1, $10 -; MIPS64ELR6-NEXT: seh $1, $1 +; MIPS64ELR6-NEXT: .insn ; MIPS64ELR6-NEXT: # %bb.3: # %entry ; MIPS64ELR6-NEXT: sw $1, 12($sp) # 4-byte Folded Spill ; MIPS64ELR6-NEXT: # %bb.4: # %entry @@ -2514,8 +2530,12 @@ define i16 @test_umin_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS-NEXT: $BB7_1: # %entry ; MIPS-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPS-NEXT: ll $2, 0($6) -; MIPS-NEXT: sltu $5, $2, $7 -; MIPS-NEXT: move $3, $2 +; MIPS-NEXT: srav $4, $2, $10 +; MIPS-NEXT: andi $4, $4, 65535 +; MIPS-NEXT: or $1, $zero, $4 +; MIPS-NEXT: sllv $4, $4, $10 +; MIPS-NEXT: sltu $5, $4, $7 +; MIPS-NEXT: move $3, $4 ; MIPS-NEXT: movz $3, $7, $5 ; MIPS-NEXT: and $3, $3, $8 ; MIPS-NEXT: and $4, $2, $9 @@ -2524,9 +2544,7 @@ define i16 @test_umin_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS-NEXT: beqz $4, $BB7_1 ; MIPS-NEXT: nop ; MIPS-NEXT: # %bb.2: # %entry -; MIPS-NEXT: and $1, $2, $8 -; MIPS-NEXT: srlv $1, $1, $10 -; MIPS-NEXT: seh $1, $1 +; MIPS-NEXT: .insn ; MIPS-NEXT: # %bb.3: # %entry ; MIPS-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MIPS-NEXT: # %bb.4: # %entry @@ -2554,8 +2572,12 @@ define i16 @test_umin_16(ptr nocapture %ptr, i16 signext %val) { ; MIPSR6-NEXT: $BB7_1: # %entry ; MIPSR6-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPSR6-NEXT: ll $2, 0($6) -; MIPSR6-NEXT: sltu $5, $2, $7 -; MIPSR6-NEXT: selnez $3, $2, $5 +; MIPSR6-NEXT: srav $4, $2, $10 +; MIPSR6-NEXT: andi $4, $4, 65535 +; MIPSR6-NEXT: or $1, $zero, $4 +; MIPSR6-NEXT: sllv $4, $4, $10 +; MIPSR6-NEXT: sltu $5, $4, $7 +; MIPSR6-NEXT: selnez $3, $4, $5 ; MIPSR6-NEXT: seleqz $5, $7, $5 ; MIPSR6-NEXT: or $3, $3, $5 ; MIPSR6-NEXT: and $3, $3, $8 @@ -2563,10 +2585,9 @@ define i16 @test_umin_16(ptr nocapture %ptr, i16 signext %val) { ; MIPSR6-NEXT: or $4, $4, $3 ; MIPSR6-NEXT: sc $4, 0($6) ; MIPSR6-NEXT: beqzc $4, $BB7_1 +; MIPSR6-NEXT: nop ; MIPSR6-NEXT: # %bb.2: # %entry -; MIPSR6-NEXT: and $1, $2, $8 -; MIPSR6-NEXT: srlv $1, $1, $10 -; MIPSR6-NEXT: seh $1, $1 +; MIPSR6-NEXT: .insn ; MIPSR6-NEXT: # %bb.3: # %entry ; MIPSR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MIPSR6-NEXT: # %bb.4: # %entry @@ -2593,8 +2614,12 @@ define i16 @test_umin_16(ptr nocapture %ptr, i16 signext %val) { ; MM-NEXT: $BB7_1: # %entry ; MM-NEXT: # =>This Inner Loop Header: Depth=1 ; MM-NEXT: ll $2, 0($6) -; MM-NEXT: sltu $5, $2, $7 -; MM-NEXT: or $3, $2, $zero +; MM-NEXT: srav $4, $2, $10 +; MM-NEXT: andi $4, $4, 65535 +; MM-NEXT: or $1, $zero, $4 +; MM-NEXT: sllv $4, $4, $10 +; MM-NEXT: sltu $5, $4, $7 +; MM-NEXT: or $3, $4, $zero ; MM-NEXT: movz $3, $7, $5 ; MM-NEXT: and $3, $3, $8 ; MM-NEXT: and $4, $2, $9 @@ -2602,9 +2627,7 @@ define i16 @test_umin_16(ptr nocapture %ptr, i16 signext %val) { ; MM-NEXT: sc $4, 0($6) ; MM-NEXT: beqzc $4, $BB7_1 ; MM-NEXT: # %bb.2: # %entry -; MM-NEXT: and $1, $2, $8 -; MM-NEXT: srlv $1, $1, $10 -; MM-NEXT: seh $1, $1 +; MM-NEXT: .insn ; MM-NEXT: # %bb.3: # %entry ; MM-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MM-NEXT: # %bb.4: # %entry @@ -2631,8 +2654,12 @@ define i16 @test_umin_16(ptr nocapture %ptr, i16 signext %val) { ; MMR6-NEXT: $BB7_1: # %entry ; MMR6-NEXT: # =>This Inner Loop Header: Depth=1 ; MMR6-NEXT: ll $2, 0($6) -; MMR6-NEXT: sltu $5, $2, $7 -; MMR6-NEXT: selnez $3, $2, $5 +; MMR6-NEXT: srav $4, $2, $10 +; MMR6-NEXT: andi $4, $4, 65535 +; MMR6-NEXT: or $1, $zero, $4 +; MMR6-NEXT: sllv $4, $4, $10 +; MMR6-NEXT: sltu $5, $4, $7 +; MMR6-NEXT: selnez $3, $4, $5 ; MMR6-NEXT: seleqz $5, $7, $5 ; MMR6-NEXT: or $3, $3, $5 ; MMR6-NEXT: and $3, $3, $8 @@ -2641,9 +2668,7 @@ define i16 @test_umin_16(ptr nocapture %ptr, i16 signext %val) { ; MMR6-NEXT: sc $4, 0($6) ; MMR6-NEXT: beqc $4, $zero, $BB7_1 ; MMR6-NEXT: # %bb.2: # %entry -; MMR6-NEXT: and $1, $2, $8 -; MMR6-NEXT: srlv $1, $1, $10 -; MMR6-NEXT: seh $1, $1 +; MMR6-NEXT: .insn ; MMR6-NEXT: # %bb.3: # %entry ; MMR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MMR6-NEXT: # %bb.4: # %entry @@ -2669,10 +2694,13 @@ define i16 @test_umin_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS32-NEXT: $BB7_1: # %entry ; MIPS32-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPS32-NEXT: ll $2, 0($6) -; MIPS32-NEXT: and $2, $2, $8 -; MIPS32-NEXT: and $7, $7, $8 -; MIPS32-NEXT: sltu $5, $2, $7 -; MIPS32-NEXT: move $3, $2 +; MIPS32-NEXT: srav $4, $2, $10 +; MIPS32-NEXT: sll $4, $4, 16 +; MIPS32-NEXT: srl $4, $4, 16 +; MIPS32-NEXT: or $1, $zero, $4 +; MIPS32-NEXT: sllv $4, $4, $10 +; MIPS32-NEXT: sltu $5, $4, $7 +; MIPS32-NEXT: move $3, $4 ; MIPS32-NEXT: movz $3, $7, $5 ; MIPS32-NEXT: and $3, $3, $8 ; MIPS32-NEXT: and $4, $2, $9 @@ -2681,10 +2709,7 @@ define i16 @test_umin_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS32-NEXT: beqz $4, $BB7_1 ; MIPS32-NEXT: nop ; MIPS32-NEXT: # %bb.2: # %entry -; MIPS32-NEXT: and $1, $2, $8 -; MIPS32-NEXT: srlv $1, $1, $10 -; MIPS32-NEXT: sll $1, $1, 16 -; MIPS32-NEXT: sra $1, $1, 16 +; MIPS32-NEXT: .insn ; MIPS32-NEXT: # %bb.3: # %entry ; MIPS32-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MIPS32-NEXT: # %bb.4: # %entry @@ -2694,7 +2719,6 @@ define i16 @test_umin_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS32-NEXT: jr $ra ; MIPS32-NEXT: nop ; -; ; MIPSEL-LABEL: test_umin_16: ; MIPSEL: # %bb.0: # %entry ; MIPSEL-NEXT: addiu $sp, $sp, -8 @@ -2712,10 +2736,12 @@ define i16 @test_umin_16(ptr nocapture %ptr, i16 signext %val) { ; MIPSEL-NEXT: $BB7_1: # %entry ; MIPSEL-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPSEL-NEXT: ll $2, 0($6) -; MIPSEL-NEXT: and $2, $2, $8 -; MIPSEL-NEXT: and $7, $7, $8 -; MIPSEL-NEXT: sltu $5, $2, $7 -; MIPSEL-NEXT: move $3, $2 +; MIPSEL-NEXT: srav $4, $2, $10 +; MIPSEL-NEXT: andi $4, $4, 65535 +; MIPSEL-NEXT: or $1, $zero, $4 +; MIPSEL-NEXT: sllv $4, $4, $10 +; MIPSEL-NEXT: sltu $5, $4, $7 +; MIPSEL-NEXT: move $3, $4 ; MIPSEL-NEXT: movz $3, $7, $5 ; MIPSEL-NEXT: and $3, $3, $8 ; MIPSEL-NEXT: and $4, $2, $9 @@ -2724,9 +2750,7 @@ define i16 @test_umin_16(ptr nocapture %ptr, i16 signext %val) { ; MIPSEL-NEXT: beqz $4, $BB7_1 ; MIPSEL-NEXT: nop ; MIPSEL-NEXT: # %bb.2: # %entry -; MIPSEL-NEXT: and $1, $2, $8 -; MIPSEL-NEXT: srlv $1, $1, $10 -; MIPSEL-NEXT: seh $1, $1 +; MIPSEL-NEXT: .insn ; MIPSEL-NEXT: # %bb.3: # %entry ; MIPSEL-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MIPSEL-NEXT: # %bb.4: # %entry @@ -2753,10 +2777,12 @@ define i16 @test_umin_16(ptr nocapture %ptr, i16 signext %val) { ; MIPSELR6-NEXT: $BB7_1: # %entry ; MIPSELR6-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPSELR6-NEXT: ll $2, 0($6) -; MIPSELR6-NEXT: and $2, $2, $8 -; MIPSELR6-NEXT: and $7, $7, $8 -; MIPSELR6-NEXT: sltu $5, $2, $7 -; MIPSELR6-NEXT: selnez $3, $2, $5 +; MIPSELR6-NEXT: srav $4, $2, $10 +; MIPSELR6-NEXT: andi $4, $4, 65535 +; MIPSELR6-NEXT: or $1, $zero, $4 +; MIPSELR6-NEXT: sllv $4, $4, $10 +; MIPSELR6-NEXT: sltu $5, $4, $7 +; MIPSELR6-NEXT: selnez $3, $4, $5 ; MIPSELR6-NEXT: seleqz $5, $7, $5 ; MIPSELR6-NEXT: or $3, $3, $5 ; MIPSELR6-NEXT: and $3, $3, $8 @@ -2764,10 +2790,9 @@ define i16 @test_umin_16(ptr nocapture %ptr, i16 signext %val) { ; MIPSELR6-NEXT: or $4, $4, $3 ; MIPSELR6-NEXT: sc $4, 0($6) ; MIPSELR6-NEXT: beqzc $4, $BB7_1 +; MIPSELR6-NEXT: nop ; MIPSELR6-NEXT: # %bb.2: # %entry -; MIPSELR6-NEXT: and $1, $2, $8 -; MIPSELR6-NEXT: srlv $1, $1, $10 -; MIPSELR6-NEXT: seh $1, $1 +; MIPSELR6-NEXT: .insn ; MIPSELR6-NEXT: # %bb.3: # %entry ; MIPSELR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MIPSELR6-NEXT: # %bb.4: # %entry @@ -2793,10 +2818,12 @@ define i16 @test_umin_16(ptr nocapture %ptr, i16 signext %val) { ; MMEL-NEXT: $BB7_1: # %entry ; MMEL-NEXT: # =>This Inner Loop Header: Depth=1 ; MMEL-NEXT: ll $2, 0($6) -; MMEL-NEXT: and $2, $2, $8 -; MMEL-NEXT: and $7, $7, $8 -; MMEL-NEXT: sltu $5, $2, $7 -; MMEL-NEXT: or $3, $2, $zero +; MMEL-NEXT: srav $4, $2, $10 +; MMEL-NEXT: andi $4, $4, 65535 +; MMEL-NEXT: or $1, $zero, $4 +; MMEL-NEXT: sllv $4, $4, $10 +; MMEL-NEXT: sltu $5, $4, $7 +; MMEL-NEXT: or $3, $4, $zero ; MMEL-NEXT: movz $3, $7, $5 ; MMEL-NEXT: and $3, $3, $8 ; MMEL-NEXT: and $4, $2, $9 @@ -2804,9 +2831,7 @@ define i16 @test_umin_16(ptr nocapture %ptr, i16 signext %val) { ; MMEL-NEXT: sc $4, 0($6) ; MMEL-NEXT: beqzc $4, $BB7_1 ; MMEL-NEXT: # %bb.2: # %entry -; MMEL-NEXT: and $1, $2, $8 -; MMEL-NEXT: srlv $1, $1, $10 -; MMEL-NEXT: seh $1, $1 +; MMEL-NEXT: .insn ; MMEL-NEXT: # %bb.3: # %entry ; MMEL-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MMEL-NEXT: # %bb.4: # %entry @@ -2832,10 +2857,12 @@ define i16 @test_umin_16(ptr nocapture %ptr, i16 signext %val) { ; MMELR6-NEXT: $BB7_1: # %entry ; MMELR6-NEXT: # =>This Inner Loop Header: Depth=1 ; MMELR6-NEXT: ll $2, 0($6) -; MMELR6-NEXT: and $2, $2, $8 -; MMELR6-NEXT: and $7, $7, $8 -; MMELR6-NEXT: sltu $5, $2, $7 -; MMELR6-NEXT: selnez $3, $2, $5 +; MMELR6-NEXT: srav $4, $2, $10 +; MMELR6-NEXT: andi $4, $4, 65535 +; MMELR6-NEXT: or $1, $zero, $4 +; MMELR6-NEXT: sllv $4, $4, $10 +; MMELR6-NEXT: sltu $5, $4, $7 +; MMELR6-NEXT: selnez $3, $4, $5 ; MMELR6-NEXT: seleqz $5, $7, $5 ; MMELR6-NEXT: or $3, $3, $5 ; MMELR6-NEXT: and $3, $3, $8 @@ -2844,9 +2871,7 @@ define i16 @test_umin_16(ptr nocapture %ptr, i16 signext %val) { ; MMELR6-NEXT: sc $4, 0($6) ; MMELR6-NEXT: beqc $4, $zero, $BB7_1 ; MMELR6-NEXT: # %bb.2: # %entry -; MMELR6-NEXT: and $1, $2, $8 -; MMELR6-NEXT: srlv $1, $1, $10 -; MMELR6-NEXT: seh $1, $1 +; MMELR6-NEXT: .insn ; MMELR6-NEXT: # %bb.3: # %entry ; MMELR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MMELR6-NEXT: # %bb.4: # %entry @@ -2873,8 +2898,12 @@ define i16 @test_umin_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS64-NEXT: .LBB7_1: # %entry ; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPS64-NEXT: ll $2, 0($6) -; MIPS64-NEXT: sltu $5, $2, $7 -; MIPS64-NEXT: move $3, $2 +; MIPS64-NEXT: srav $4, $2, $10 +; MIPS64-NEXT: andi $4, $4, 65535 +; MIPS64-NEXT: or $1, $zero, $4 +; MIPS64-NEXT: sllv $4, $4, $10 +; MIPS64-NEXT: sltu $5, $4, $7 +; MIPS64-NEXT: move $3, $4 ; MIPS64-NEXT: movz $3, $7, $5 ; MIPS64-NEXT: and $3, $3, $8 ; MIPS64-NEXT: and $4, $2, $9 @@ -2883,9 +2912,7 @@ define i16 @test_umin_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS64-NEXT: beqz $4, .LBB7_1 ; MIPS64-NEXT: nop ; MIPS64-NEXT: # %bb.2: # %entry -; MIPS64-NEXT: and $1, $2, $8 -; MIPS64-NEXT: srlv $1, $1, $10 -; MIPS64-NEXT: seh $1, $1 +; MIPS64-NEXT: .insn ; MIPS64-NEXT: # %bb.3: # %entry ; MIPS64-NEXT: sw $1, 12($sp) # 4-byte Folded Spill ; MIPS64-NEXT: # %bb.4: # %entry @@ -2913,8 +2940,12 @@ define i16 @test_umin_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS64R6-NEXT: .LBB7_1: # %entry ; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPS64R6-NEXT: ll $2, 0($6) -; MIPS64R6-NEXT: sltu $5, $2, $7 -; MIPS64R6-NEXT: selnez $3, $2, $5 +; MIPS64R6-NEXT: srav $4, $2, $10 +; MIPS64R6-NEXT: andi $4, $4, 65535 +; MIPS64R6-NEXT: or $1, $zero, $4 +; MIPS64R6-NEXT: sllv $4, $4, $10 +; MIPS64R6-NEXT: sltu $5, $4, $7 +; MIPS64R6-NEXT: selnez $3, $4, $5 ; MIPS64R6-NEXT: seleqz $5, $7, $5 ; MIPS64R6-NEXT: or $3, $3, $5 ; MIPS64R6-NEXT: and $3, $3, $8 @@ -2922,10 +2953,9 @@ define i16 @test_umin_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS64R6-NEXT: or $4, $4, $3 ; MIPS64R6-NEXT: sc $4, 0($6) ; MIPS64R6-NEXT: beqzc $4, .LBB7_1 +; MIPS64R6-NEXT: nop ; MIPS64R6-NEXT: # %bb.2: # %entry -; MIPS64R6-NEXT: and $1, $2, $8 -; MIPS64R6-NEXT: srlv $1, $1, $10 -; MIPS64R6-NEXT: seh $1, $1 +; MIPS64R6-NEXT: .insn ; MIPS64R6-NEXT: # %bb.3: # %entry ; MIPS64R6-NEXT: sw $1, 12($sp) # 4-byte Folded Spill ; MIPS64R6-NEXT: # %bb.4: # %entry @@ -2951,10 +2981,12 @@ define i16 @test_umin_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS64EL-NEXT: .LBB7_1: # %entry ; MIPS64EL-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPS64EL-NEXT: ll $2, 0($6) -; MIPS64EL-NEXT: and $2, $2, $8 -; MIPS64EL-NEXT: and $7, $7, $8 -; MIPS64EL-NEXT: sltu $5, $2, $7 -; MIPS64EL-NEXT: move $3, $2 +; MIPS64EL-NEXT: srav $4, $2, $10 +; MIPS64EL-NEXT: andi $4, $4, 65535 +; MIPS64EL-NEXT: or $1, $zero, $4 +; MIPS64EL-NEXT: sllv $4, $4, $10 +; MIPS64EL-NEXT: sltu $5, $4, $7 +; MIPS64EL-NEXT: move $3, $4 ; MIPS64EL-NEXT: movz $3, $7, $5 ; MIPS64EL-NEXT: and $3, $3, $8 ; MIPS64EL-NEXT: and $4, $2, $9 @@ -2963,9 +2995,7 @@ define i16 @test_umin_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS64EL-NEXT: beqz $4, .LBB7_1 ; MIPS64EL-NEXT: nop ; MIPS64EL-NEXT: # %bb.2: # %entry -; MIPS64EL-NEXT: and $1, $2, $8 -; MIPS64EL-NEXT: srlv $1, $1, $10 -; MIPS64EL-NEXT: seh $1, $1 +; MIPS64EL-NEXT: .insn ; MIPS64EL-NEXT: # %bb.3: # %entry ; MIPS64EL-NEXT: sw $1, 12($sp) # 4-byte Folded Spill ; MIPS64EL-NEXT: # %bb.4: # %entry @@ -2992,10 +3022,12 @@ define i16 @test_umin_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS64ELR6-NEXT: .LBB7_1: # %entry ; MIPS64ELR6-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPS64ELR6-NEXT: ll $2, 0($6) -; MIPS64ELR6-NEXT: and $2, $2, $8 -; MIPS64ELR6-NEXT: and $7, $7, $8 -; MIPS64ELR6-NEXT: sltu $5, $2, $7 -; MIPS64ELR6-NEXT: selnez $3, $2, $5 +; MIPS64ELR6-NEXT: srav $4, $2, $10 +; MIPS64ELR6-NEXT: andi $4, $4, 65535 +; MIPS64ELR6-NEXT: or $1, $zero, $4 +; MIPS64ELR6-NEXT: sllv $4, $4, $10 +; MIPS64ELR6-NEXT: sltu $5, $4, $7 +; MIPS64ELR6-NEXT: selnez $3, $4, $5 ; MIPS64ELR6-NEXT: seleqz $5, $7, $5 ; MIPS64ELR6-NEXT: or $3, $3, $5 ; MIPS64ELR6-NEXT: and $3, $3, $8 @@ -3003,10 +3035,9 @@ define i16 @test_umin_16(ptr nocapture %ptr, i16 signext %val) { ; MIPS64ELR6-NEXT: or $4, $4, $3 ; MIPS64ELR6-NEXT: sc $4, 0($6) ; MIPS64ELR6-NEXT: beqzc $4, .LBB7_1 +; MIPS64ELR6-NEXT: nop ; MIPS64ELR6-NEXT: # %bb.2: # %entry -; MIPS64ELR6-NEXT: and $1, $2, $8 -; MIPS64ELR6-NEXT: srlv $1, $1, $10 -; MIPS64ELR6-NEXT: seh $1, $1 +; MIPS64ELR6-NEXT: .insn ; MIPS64ELR6-NEXT: # %bb.3: # %entry ; MIPS64ELR6-NEXT: sw $1, 12($sp) # 4-byte Folded Spill ; MIPS64ELR6-NEXT: # %bb.4: # %entry @@ -3039,8 +3070,12 @@ define i8 @test_max_8(ptr nocapture %ptr, i8 signext %val) { ; MIPS-NEXT: $BB8_1: # %entry ; MIPS-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPS-NEXT: ll $2, 0($6) -; MIPS-NEXT: slt $5, $2, $7 -; MIPS-NEXT: move $3, $2 +; MIPS-NEXT: srav $4, $2, $10 +; MIPS-NEXT: seb $4, $4 +; MIPS-NEXT: or $1, $zero, $4 +; MIPS-NEXT: sllv $4, $4, $10 +; MIPS-NEXT: slt $5, $4, $7 +; MIPS-NEXT: move $3, $4 ; MIPS-NEXT: movn $3, $7, $5 ; MIPS-NEXT: and $3, $3, $8 ; MIPS-NEXT: and $4, $2, $9 @@ -3049,9 +3084,7 @@ define i8 @test_max_8(ptr nocapture %ptr, i8 signext %val) { ; MIPS-NEXT: beqz $4, $BB8_1 ; MIPS-NEXT: nop ; MIPS-NEXT: # %bb.2: # %entry -; MIPS-NEXT: and $1, $2, $8 -; MIPS-NEXT: srlv $1, $1, $10 -; MIPS-NEXT: seb $1, $1 +; MIPS-NEXT: .insn ; MIPS-NEXT: # %bb.3: # %entry ; MIPS-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MIPS-NEXT: # %bb.4: # %entry @@ -3079,8 +3112,12 @@ define i8 @test_max_8(ptr nocapture %ptr, i8 signext %val) { ; MIPSR6-NEXT: $BB8_1: # %entry ; MIPSR6-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPSR6-NEXT: ll $2, 0($6) -; MIPSR6-NEXT: slt $5, $2, $7 -; MIPSR6-NEXT: seleqz $3, $2, $5 +; MIPSR6-NEXT: srav $4, $2, $10 +; MIPSR6-NEXT: seb $4, $4 +; MIPSR6-NEXT: or $1, $zero, $4 +; MIPSR6-NEXT: sllv $4, $4, $10 +; MIPSR6-NEXT: slt $5, $4, $7 +; MIPSR6-NEXT: seleqz $3, $4, $5 ; MIPSR6-NEXT: selnez $5, $7, $5 ; MIPSR6-NEXT: or $3, $3, $5 ; MIPSR6-NEXT: and $3, $3, $8 @@ -3088,10 +3125,9 @@ define i8 @test_max_8(ptr nocapture %ptr, i8 signext %val) { ; MIPSR6-NEXT: or $4, $4, $3 ; MIPSR6-NEXT: sc $4, 0($6) ; MIPSR6-NEXT: beqzc $4, $BB8_1 +; MIPSR6-NEXT: nop ; MIPSR6-NEXT: # %bb.2: # %entry -; MIPSR6-NEXT: and $1, $2, $8 -; MIPSR6-NEXT: srlv $1, $1, $10 -; MIPSR6-NEXT: seb $1, $1 +; MIPSR6-NEXT: .insn ; MIPSR6-NEXT: # %bb.3: # %entry ; MIPSR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MIPSR6-NEXT: # %bb.4: # %entry @@ -3118,8 +3154,12 @@ define i8 @test_max_8(ptr nocapture %ptr, i8 signext %val) { ; MM-NEXT: $BB8_1: # %entry ; MM-NEXT: # =>This Inner Loop Header: Depth=1 ; MM-NEXT: ll $2, 0($6) -; MM-NEXT: slt $5, $2, $7 -; MM-NEXT: or $3, $2, $zero +; MM-NEXT: srav $4, $2, $10 +; MM-NEXT: seb $4, $4 +; MM-NEXT: or $1, $zero, $4 +; MM-NEXT: sllv $4, $4, $10 +; MM-NEXT: slt $5, $4, $7 +; MM-NEXT: or $3, $4, $zero ; MM-NEXT: movn $3, $7, $5 ; MM-NEXT: and $3, $3, $8 ; MM-NEXT: and $4, $2, $9 @@ -3127,9 +3167,7 @@ define i8 @test_max_8(ptr nocapture %ptr, i8 signext %val) { ; MM-NEXT: sc $4, 0($6) ; MM-NEXT: beqzc $4, $BB8_1 ; MM-NEXT: # %bb.2: # %entry -; MM-NEXT: and $1, $2, $8 -; MM-NEXT: srlv $1, $1, $10 -; MM-NEXT: seb $1, $1 +; MM-NEXT: .insn ; MM-NEXT: # %bb.3: # %entry ; MM-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MM-NEXT: # %bb.4: # %entry @@ -3156,8 +3194,12 @@ define i8 @test_max_8(ptr nocapture %ptr, i8 signext %val) { ; MMR6-NEXT: $BB8_1: # %entry ; MMR6-NEXT: # =>This Inner Loop Header: Depth=1 ; MMR6-NEXT: ll $2, 0($6) -; MMR6-NEXT: slt $5, $2, $7 -; MMR6-NEXT: seleqz $3, $2, $5 +; MMR6-NEXT: srav $4, $2, $10 +; MMR6-NEXT: seb $4, $4 +; MMR6-NEXT: or $1, $zero, $4 +; MMR6-NEXT: sllv $4, $4, $10 +; MMR6-NEXT: slt $5, $4, $7 +; MMR6-NEXT: seleqz $3, $4, $5 ; MMR6-NEXT: selnez $5, $7, $5 ; MMR6-NEXT: or $3, $3, $5 ; MMR6-NEXT: and $3, $3, $8 @@ -3166,9 +3208,7 @@ define i8 @test_max_8(ptr nocapture %ptr, i8 signext %val) { ; MMR6-NEXT: sc $4, 0($6) ; MMR6-NEXT: beqc $4, $zero, $BB8_1 ; MMR6-NEXT: # %bb.2: # %entry -; MMR6-NEXT: and $1, $2, $8 -; MMR6-NEXT: srlv $1, $1, $10 -; MMR6-NEXT: seb $1, $1 +; MMR6-NEXT: .insn ; MMR6-NEXT: # %bb.3: # %entry ; MMR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MMR6-NEXT: # %bb.4: # %entry @@ -3194,14 +3234,13 @@ define i8 @test_max_8(ptr nocapture %ptr, i8 signext %val) { ; MIPS32-NEXT: $BB8_1: # %entry ; MIPS32-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPS32-NEXT: ll $2, 0($6) -; MIPS32-NEXT: srav $2, $2, $10 -; MIPS32-NEXT: srav $7, $7, $10 -; MIPS32-NEXT: sll $2, $2, 24 -; MIPS32-NEXT: sra $2, $2, 24 -; MIPS32-NEXT: sll $7, $7, 24 -; MIPS32-NEXT: sra $7, $7, 24 -; MIPS32-NEXT: slt $5, $2, $7 -; MIPS32-NEXT: move $3, $2 +; MIPS32-NEXT: srav $4, $2, $10 +; MIPS32-NEXT: sll $4, $4, 24 +; MIPS32-NEXT: sra $4, $4, 24 +; MIPS32-NEXT: or $1, $zero, $4 +; MIPS32-NEXT: sllv $4, $4, $10 +; MIPS32-NEXT: slt $5, $4, $7 +; MIPS32-NEXT: move $3, $4 ; MIPS32-NEXT: movn $3, $7, $5 ; MIPS32-NEXT: and $3, $3, $8 ; MIPS32-NEXT: and $4, $2, $9 @@ -3210,10 +3249,7 @@ define i8 @test_max_8(ptr nocapture %ptr, i8 signext %val) { ; MIPS32-NEXT: beqz $4, $BB8_1 ; MIPS32-NEXT: nop ; MIPS32-NEXT: # %bb.2: # %entry -; MIPS32-NEXT: and $1, $2, $8 -; MIPS32-NEXT: srlv $1, $1, $10 -; MIPS32-NEXT: sll $1, $1, 24 -; MIPS32-NEXT: sra $1, $1, 24 +; MIPS32-NEXT: .insn ; MIPS32-NEXT: # %bb.3: # %entry ; MIPS32-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MIPS32-NEXT: # %bb.4: # %entry @@ -3240,12 +3276,12 @@ define i8 @test_max_8(ptr nocapture %ptr, i8 signext %val) { ; MIPSEL-NEXT: $BB8_1: # %entry ; MIPSEL-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPSEL-NEXT: ll $2, 0($6) -; MIPSEL-NEXT: srav $2, $2, $10 -; MIPSEL-NEXT: srav $7, $7, $10 -; MIPSEL-NEXT: seb $2, $2 -; MIPSEL-NEXT: seb $7, $7 -; MIPSEL-NEXT: slt $5, $2, $7 -; MIPSEL-NEXT: move $3, $2 +; MIPSEL-NEXT: srav $4, $2, $10 +; MIPSEL-NEXT: seb $4, $4 +; MIPSEL-NEXT: or $1, $zero, $4 +; MIPSEL-NEXT: sllv $4, $4, $10 +; MIPSEL-NEXT: slt $5, $4, $7 +; MIPSEL-NEXT: move $3, $4 ; MIPSEL-NEXT: movn $3, $7, $5 ; MIPSEL-NEXT: and $3, $3, $8 ; MIPSEL-NEXT: and $4, $2, $9 @@ -3254,9 +3290,7 @@ define i8 @test_max_8(ptr nocapture %ptr, i8 signext %val) { ; MIPSEL-NEXT: beqz $4, $BB8_1 ; MIPSEL-NEXT: nop ; MIPSEL-NEXT: # %bb.2: # %entry -; MIPSEL-NEXT: and $1, $2, $8 -; MIPSEL-NEXT: srlv $1, $1, $10 -; MIPSEL-NEXT: seb $1, $1 +; MIPSEL-NEXT: .insn ; MIPSEL-NEXT: # %bb.3: # %entry ; MIPSEL-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MIPSEL-NEXT: # %bb.4: # %entry @@ -3283,12 +3317,12 @@ define i8 @test_max_8(ptr nocapture %ptr, i8 signext %val) { ; MIPSELR6-NEXT: $BB8_1: # %entry ; MIPSELR6-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPSELR6-NEXT: ll $2, 0($6) -; MIPSELR6-NEXT: srav $2, $2, $10 -; MIPSELR6-NEXT: srav $7, $7, $10 -; MIPSELR6-NEXT: seb $2, $2 -; MIPSELR6-NEXT: seb $7, $7 -; MIPSELR6-NEXT: slt $5, $2, $7 -; MIPSELR6-NEXT: seleqz $3, $2, $5 +; MIPSELR6-NEXT: srav $4, $2, $10 +; MIPSELR6-NEXT: seb $4, $4 +; MIPSELR6-NEXT: or $1, $zero, $4 +; MIPSELR6-NEXT: sllv $4, $4, $10 +; MIPSELR6-NEXT: slt $5, $4, $7 +; MIPSELR6-NEXT: seleqz $3, $4, $5 ; MIPSELR6-NEXT: selnez $5, $7, $5 ; MIPSELR6-NEXT: or $3, $3, $5 ; MIPSELR6-NEXT: and $3, $3, $8 @@ -3296,10 +3330,9 @@ define i8 @test_max_8(ptr nocapture %ptr, i8 signext %val) { ; MIPSELR6-NEXT: or $4, $4, $3 ; MIPSELR6-NEXT: sc $4, 0($6) ; MIPSELR6-NEXT: beqzc $4, $BB8_1 +; MIPSELR6-NEXT: nop ; MIPSELR6-NEXT: # %bb.2: # %entry -; MIPSELR6-NEXT: and $1, $2, $8 -; MIPSELR6-NEXT: srlv $1, $1, $10 -; MIPSELR6-NEXT: seb $1, $1 +; MIPSELR6-NEXT: .insn ; MIPSELR6-NEXT: # %bb.3: # %entry ; MIPSELR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MIPSELR6-NEXT: # %bb.4: # %entry @@ -3325,12 +3358,12 @@ define i8 @test_max_8(ptr nocapture %ptr, i8 signext %val) { ; MMEL-NEXT: $BB8_1: # %entry ; MMEL-NEXT: # =>This Inner Loop Header: Depth=1 ; MMEL-NEXT: ll $2, 0($6) -; MMEL-NEXT: srav $2, $2, $10 -; MMEL-NEXT: srav $7, $7, $10 -; MMEL-NEXT: seb $2, $2 -; MMEL-NEXT: seb $7, $7 -; MMEL-NEXT: slt $5, $2, $7 -; MMEL-NEXT: or $3, $2, $zero +; MMEL-NEXT: srav $4, $2, $10 +; MMEL-NEXT: seb $4, $4 +; MMEL-NEXT: or $1, $zero, $4 +; MMEL-NEXT: sllv $4, $4, $10 +; MMEL-NEXT: slt $5, $4, $7 +; MMEL-NEXT: or $3, $4, $zero ; MMEL-NEXT: movn $3, $7, $5 ; MMEL-NEXT: and $3, $3, $8 ; MMEL-NEXT: and $4, $2, $9 @@ -3338,9 +3371,7 @@ define i8 @test_max_8(ptr nocapture %ptr, i8 signext %val) { ; MMEL-NEXT: sc $4, 0($6) ; MMEL-NEXT: beqzc $4, $BB8_1 ; MMEL-NEXT: # %bb.2: # %entry -; MMEL-NEXT: and $1, $2, $8 -; MMEL-NEXT: srlv $1, $1, $10 -; MMEL-NEXT: seb $1, $1 +; MMEL-NEXT: .insn ; MMEL-NEXT: # %bb.3: # %entry ; MMEL-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MMEL-NEXT: # %bb.4: # %entry @@ -3366,12 +3397,12 @@ define i8 @test_max_8(ptr nocapture %ptr, i8 signext %val) { ; MMELR6-NEXT: $BB8_1: # %entry ; MMELR6-NEXT: # =>This Inner Loop Header: Depth=1 ; MMELR6-NEXT: ll $2, 0($6) -; MMELR6-NEXT: srav $2, $2, $10 -; MMELR6-NEXT: srav $7, $7, $10 -; MMELR6-NEXT: seb $2, $2 -; MMELR6-NEXT: seb $7, $7 -; MMELR6-NEXT: slt $5, $2, $7 -; MMELR6-NEXT: seleqz $3, $2, $5 +; MMELR6-NEXT: srav $4, $2, $10 +; MMELR6-NEXT: seb $4, $4 +; MMELR6-NEXT: or $1, $zero, $4 +; MMELR6-NEXT: sllv $4, $4, $10 +; MMELR6-NEXT: slt $5, $4, $7 +; MMELR6-NEXT: seleqz $3, $4, $5 ; MMELR6-NEXT: selnez $5, $7, $5 ; MMELR6-NEXT: or $3, $3, $5 ; MMELR6-NEXT: and $3, $3, $8 @@ -3380,9 +3411,7 @@ define i8 @test_max_8(ptr nocapture %ptr, i8 signext %val) { ; MMELR6-NEXT: sc $4, 0($6) ; MMELR6-NEXT: beqc $4, $zero, $BB8_1 ; MMELR6-NEXT: # %bb.2: # %entry -; MMELR6-NEXT: and $1, $2, $8 -; MMELR6-NEXT: srlv $1, $1, $10 -; MMELR6-NEXT: seb $1, $1 +; MMELR6-NEXT: .insn ; MMELR6-NEXT: # %bb.3: # %entry ; MMELR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MMELR6-NEXT: # %bb.4: # %entry @@ -3409,8 +3438,12 @@ define i8 @test_max_8(ptr nocapture %ptr, i8 signext %val) { ; MIPS64-NEXT: .LBB8_1: # %entry ; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPS64-NEXT: ll $2, 0($6) -; MIPS64-NEXT: slt $5, $2, $7 -; MIPS64-NEXT: move $3, $2 +; MIPS64-NEXT: srav $4, $2, $10 +; MIPS64-NEXT: seb $4, $4 +; MIPS64-NEXT: or $1, $zero, $4 +; MIPS64-NEXT: sllv $4, $4, $10 +; MIPS64-NEXT: slt $5, $4, $7 +; MIPS64-NEXT: move $3, $4 ; MIPS64-NEXT: movn $3, $7, $5 ; MIPS64-NEXT: and $3, $3, $8 ; MIPS64-NEXT: and $4, $2, $9 @@ -3419,9 +3452,7 @@ define i8 @test_max_8(ptr nocapture %ptr, i8 signext %val) { ; MIPS64-NEXT: beqz $4, .LBB8_1 ; MIPS64-NEXT: nop ; MIPS64-NEXT: # %bb.2: # %entry -; MIPS64-NEXT: and $1, $2, $8 -; MIPS64-NEXT: srlv $1, $1, $10 -; MIPS64-NEXT: seb $1, $1 +; MIPS64-NEXT: .insn ; MIPS64-NEXT: # %bb.3: # %entry ; MIPS64-NEXT: sw $1, 12($sp) # 4-byte Folded Spill ; MIPS64-NEXT: # %bb.4: # %entry @@ -3449,8 +3480,12 @@ define i8 @test_max_8(ptr nocapture %ptr, i8 signext %val) { ; MIPS64R6-NEXT: .LBB8_1: # %entry ; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPS64R6-NEXT: ll $2, 0($6) -; MIPS64R6-NEXT: slt $5, $2, $7 -; MIPS64R6-NEXT: seleqz $3, $2, $5 +; MIPS64R6-NEXT: srav $4, $2, $10 +; MIPS64R6-NEXT: seb $4, $4 +; MIPS64R6-NEXT: or $1, $zero, $4 +; MIPS64R6-NEXT: sllv $4, $4, $10 +; MIPS64R6-NEXT: slt $5, $4, $7 +; MIPS64R6-NEXT: seleqz $3, $4, $5 ; MIPS64R6-NEXT: selnez $5, $7, $5 ; MIPS64R6-NEXT: or $3, $3, $5 ; MIPS64R6-NEXT: and $3, $3, $8 @@ -3458,10 +3493,9 @@ define i8 @test_max_8(ptr nocapture %ptr, i8 signext %val) { ; MIPS64R6-NEXT: or $4, $4, $3 ; MIPS64R6-NEXT: sc $4, 0($6) ; MIPS64R6-NEXT: beqzc $4, .LBB8_1 +; MIPS64R6-NEXT: nop ; MIPS64R6-NEXT: # %bb.2: # %entry -; MIPS64R6-NEXT: and $1, $2, $8 -; MIPS64R6-NEXT: srlv $1, $1, $10 -; MIPS64R6-NEXT: seb $1, $1 +; MIPS64R6-NEXT: .insn ; MIPS64R6-NEXT: # %bb.3: # %entry ; MIPS64R6-NEXT: sw $1, 12($sp) # 4-byte Folded Spill ; MIPS64R6-NEXT: # %bb.4: # %entry @@ -3487,12 +3521,12 @@ define i8 @test_max_8(ptr nocapture %ptr, i8 signext %val) { ; MIPS64EL-NEXT: .LBB8_1: # %entry ; MIPS64EL-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPS64EL-NEXT: ll $2, 0($6) -; MIPS64EL-NEXT: srav $2, $2, $10 -; MIPS64EL-NEXT: srav $7, $7, $10 -; MIPS64EL-NEXT: seb $2, $2 -; MIPS64EL-NEXT: seb $7, $7 -; MIPS64EL-NEXT: slt $5, $2, $7 -; MIPS64EL-NEXT: move $3, $2 +; MIPS64EL-NEXT: srav $4, $2, $10 +; MIPS64EL-NEXT: seb $4, $4 +; MIPS64EL-NEXT: or $1, $zero, $4 +; MIPS64EL-NEXT: sllv $4, $4, $10 +; MIPS64EL-NEXT: slt $5, $4, $7 +; MIPS64EL-NEXT: move $3, $4 ; MIPS64EL-NEXT: movn $3, $7, $5 ; MIPS64EL-NEXT: and $3, $3, $8 ; MIPS64EL-NEXT: and $4, $2, $9 @@ -3501,9 +3535,7 @@ define i8 @test_max_8(ptr nocapture %ptr, i8 signext %val) { ; MIPS64EL-NEXT: beqz $4, .LBB8_1 ; MIPS64EL-NEXT: nop ; MIPS64EL-NEXT: # %bb.2: # %entry -; MIPS64EL-NEXT: and $1, $2, $8 -; MIPS64EL-NEXT: srlv $1, $1, $10 -; MIPS64EL-NEXT: seb $1, $1 +; MIPS64EL-NEXT: .insn ; MIPS64EL-NEXT: # %bb.3: # %entry ; MIPS64EL-NEXT: sw $1, 12($sp) # 4-byte Folded Spill ; MIPS64EL-NEXT: # %bb.4: # %entry @@ -3530,12 +3562,12 @@ define i8 @test_max_8(ptr nocapture %ptr, i8 signext %val) { ; MIPS64ELR6-NEXT: .LBB8_1: # %entry ; MIPS64ELR6-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPS64ELR6-NEXT: ll $2, 0($6) -; MIPS64ELR6-NEXT: srav $2, $2, $10 -; MIPS64ELR6-NEXT: srav $7, $7, $10 -; MIPS64ELR6-NEXT: seb $2, $2 -; MIPS64ELR6-NEXT: seb $7, $7 -; MIPS64ELR6-NEXT: slt $5, $2, $7 -; MIPS64ELR6-NEXT: seleqz $3, $2, $5 +; MIPS64ELR6-NEXT: srav $4, $2, $10 +; MIPS64ELR6-NEXT: seb $4, $4 +; MIPS64ELR6-NEXT: or $1, $zero, $4 +; MIPS64ELR6-NEXT: sllv $4, $4, $10 +; MIPS64ELR6-NEXT: slt $5, $4, $7 +; MIPS64ELR6-NEXT: seleqz $3, $4, $5 ; MIPS64ELR6-NEXT: selnez $5, $7, $5 ; MIPS64ELR6-NEXT: or $3, $3, $5 ; MIPS64ELR6-NEXT: and $3, $3, $8 @@ -3543,10 +3575,9 @@ define i8 @test_max_8(ptr nocapture %ptr, i8 signext %val) { ; MIPS64ELR6-NEXT: or $4, $4, $3 ; MIPS64ELR6-NEXT: sc $4, 0($6) ; MIPS64ELR6-NEXT: beqzc $4, .LBB8_1 +; MIPS64ELR6-NEXT: nop ; MIPS64ELR6-NEXT: # %bb.2: # %entry -; MIPS64ELR6-NEXT: and $1, $2, $8 -; MIPS64ELR6-NEXT: srlv $1, $1, $10 -; MIPS64ELR6-NEXT: seb $1, $1 +; MIPS64ELR6-NEXT: .insn ; MIPS64ELR6-NEXT: # %bb.3: # %entry ; MIPS64ELR6-NEXT: sw $1, 12($sp) # 4-byte Folded Spill ; MIPS64ELR6-NEXT: # %bb.4: # %entry @@ -3578,8 +3609,12 @@ define i8 @test_min_8(ptr nocapture %ptr, i8 signext %val) { ; MIPS-NEXT: $BB9_1: # %entry ; MIPS-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPS-NEXT: ll $2, 0($6) -; MIPS-NEXT: slt $5, $2, $7 -; MIPS-NEXT: move $3, $2 +; MIPS-NEXT: srav $4, $2, $10 +; MIPS-NEXT: seb $4, $4 +; MIPS-NEXT: or $1, $zero, $4 +; MIPS-NEXT: sllv $4, $4, $10 +; MIPS-NEXT: slt $5, $4, $7 +; MIPS-NEXT: move $3, $4 ; MIPS-NEXT: movz $3, $7, $5 ; MIPS-NEXT: and $3, $3, $8 ; MIPS-NEXT: and $4, $2, $9 @@ -3588,9 +3623,7 @@ define i8 @test_min_8(ptr nocapture %ptr, i8 signext %val) { ; MIPS-NEXT: beqz $4, $BB9_1 ; MIPS-NEXT: nop ; MIPS-NEXT: # %bb.2: # %entry -; MIPS-NEXT: and $1, $2, $8 -; MIPS-NEXT: srlv $1, $1, $10 -; MIPS-NEXT: seb $1, $1 +; MIPS-NEXT: .insn ; MIPS-NEXT: # %bb.3: # %entry ; MIPS-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MIPS-NEXT: # %bb.4: # %entry @@ -3618,8 +3651,12 @@ define i8 @test_min_8(ptr nocapture %ptr, i8 signext %val) { ; MIPSR6-NEXT: $BB9_1: # %entry ; MIPSR6-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPSR6-NEXT: ll $2, 0($6) -; MIPSR6-NEXT: slt $5, $2, $7 -; MIPSR6-NEXT: selnez $3, $2, $5 +; MIPSR6-NEXT: srav $4, $2, $10 +; MIPSR6-NEXT: seb $4, $4 +; MIPSR6-NEXT: or $1, $zero, $4 +; MIPSR6-NEXT: sllv $4, $4, $10 +; MIPSR6-NEXT: slt $5, $4, $7 +; MIPSR6-NEXT: selnez $3, $4, $5 ; MIPSR6-NEXT: seleqz $5, $7, $5 ; MIPSR6-NEXT: or $3, $3, $5 ; MIPSR6-NEXT: and $3, $3, $8 @@ -3627,10 +3664,9 @@ define i8 @test_min_8(ptr nocapture %ptr, i8 signext %val) { ; MIPSR6-NEXT: or $4, $4, $3 ; MIPSR6-NEXT: sc $4, 0($6) ; MIPSR6-NEXT: beqzc $4, $BB9_1 +; MIPSR6-NEXT: nop ; MIPSR6-NEXT: # %bb.2: # %entry -; MIPSR6-NEXT: and $1, $2, $8 -; MIPSR6-NEXT: srlv $1, $1, $10 -; MIPSR6-NEXT: seb $1, $1 +; MIPSR6-NEXT: .insn ; MIPSR6-NEXT: # %bb.3: # %entry ; MIPSR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MIPSR6-NEXT: # %bb.4: # %entry @@ -3657,8 +3693,12 @@ define i8 @test_min_8(ptr nocapture %ptr, i8 signext %val) { ; MM-NEXT: $BB9_1: # %entry ; MM-NEXT: # =>This Inner Loop Header: Depth=1 ; MM-NEXT: ll $2, 0($6) -; MM-NEXT: slt $5, $2, $7 -; MM-NEXT: or $3, $2, $zero +; MM-NEXT: srav $4, $2, $10 +; MM-NEXT: seb $4, $4 +; MM-NEXT: or $1, $zero, $4 +; MM-NEXT: sllv $4, $4, $10 +; MM-NEXT: slt $5, $4, $7 +; MM-NEXT: or $3, $4, $zero ; MM-NEXT: movz $3, $7, $5 ; MM-NEXT: and $3, $3, $8 ; MM-NEXT: and $4, $2, $9 @@ -3666,9 +3706,7 @@ define i8 @test_min_8(ptr nocapture %ptr, i8 signext %val) { ; MM-NEXT: sc $4, 0($6) ; MM-NEXT: beqzc $4, $BB9_1 ; MM-NEXT: # %bb.2: # %entry -; MM-NEXT: and $1, $2, $8 -; MM-NEXT: srlv $1, $1, $10 -; MM-NEXT: seb $1, $1 +; MM-NEXT: .insn ; MM-NEXT: # %bb.3: # %entry ; MM-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MM-NEXT: # %bb.4: # %entry @@ -3695,8 +3733,12 @@ define i8 @test_min_8(ptr nocapture %ptr, i8 signext %val) { ; MMR6-NEXT: $BB9_1: # %entry ; MMR6-NEXT: # =>This Inner Loop Header: Depth=1 ; MMR6-NEXT: ll $2, 0($6) -; MMR6-NEXT: slt $5, $2, $7 -; MMR6-NEXT: selnez $3, $2, $5 +; MMR6-NEXT: srav $4, $2, $10 +; MMR6-NEXT: seb $4, $4 +; MMR6-NEXT: or $1, $zero, $4 +; MMR6-NEXT: sllv $4, $4, $10 +; MMR6-NEXT: slt $5, $4, $7 +; MMR6-NEXT: selnez $3, $4, $5 ; MMR6-NEXT: seleqz $5, $7, $5 ; MMR6-NEXT: or $3, $3, $5 ; MMR6-NEXT: and $3, $3, $8 @@ -3705,9 +3747,7 @@ define i8 @test_min_8(ptr nocapture %ptr, i8 signext %val) { ; MMR6-NEXT: sc $4, 0($6) ; MMR6-NEXT: beqc $4, $zero, $BB9_1 ; MMR6-NEXT: # %bb.2: # %entry -; MMR6-NEXT: and $1, $2, $8 -; MMR6-NEXT: srlv $1, $1, $10 -; MMR6-NEXT: seb $1, $1 +; MMR6-NEXT: .insn ; MMR6-NEXT: # %bb.3: # %entry ; MMR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MMR6-NEXT: # %bb.4: # %entry @@ -3733,14 +3773,13 @@ define i8 @test_min_8(ptr nocapture %ptr, i8 signext %val) { ; MIPS32-NEXT: $BB9_1: # %entry ; MIPS32-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPS32-NEXT: ll $2, 0($6) -; MIPS32-NEXT: srav $2, $2, $10 -; MIPS32-NEXT: srav $7, $7, $10 -; MIPS32-NEXT: sll $2, $2, 24 -; MIPS32-NEXT: sra $2, $2, 24 -; MIPS32-NEXT: sll $7, $7, 24 -; MIPS32-NEXT: sra $7, $7, 24 -; MIPS32-NEXT: slt $5, $2, $7 -; MIPS32-NEXT: move $3, $2 +; MIPS32-NEXT: srav $4, $2, $10 +; MIPS32-NEXT: sll $4, $4, 24 +; MIPS32-NEXT: sra $4, $4, 24 +; MIPS32-NEXT: or $1, $zero, $4 +; MIPS32-NEXT: sllv $4, $4, $10 +; MIPS32-NEXT: slt $5, $4, $7 +; MIPS32-NEXT: move $3, $4 ; MIPS32-NEXT: movz $3, $7, $5 ; MIPS32-NEXT: and $3, $3, $8 ; MIPS32-NEXT: and $4, $2, $9 @@ -3749,10 +3788,7 @@ define i8 @test_min_8(ptr nocapture %ptr, i8 signext %val) { ; MIPS32-NEXT: beqz $4, $BB9_1 ; MIPS32-NEXT: nop ; MIPS32-NEXT: # %bb.2: # %entry -; MIPS32-NEXT: and $1, $2, $8 -; MIPS32-NEXT: srlv $1, $1, $10 -; MIPS32-NEXT: sll $1, $1, 24 -; MIPS32-NEXT: sra $1, $1, 24 +; MIPS32-NEXT: .insn ; MIPS32-NEXT: # %bb.3: # %entry ; MIPS32-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MIPS32-NEXT: # %bb.4: # %entry @@ -3779,12 +3815,12 @@ define i8 @test_min_8(ptr nocapture %ptr, i8 signext %val) { ; MIPSEL-NEXT: $BB9_1: # %entry ; MIPSEL-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPSEL-NEXT: ll $2, 0($6) -; MIPSEL-NEXT: srav $2, $2, $10 -; MIPSEL-NEXT: srav $7, $7, $10 -; MIPSEL-NEXT: seb $2, $2 -; MIPSEL-NEXT: seb $7, $7 -; MIPSEL-NEXT: slt $5, $2, $7 -; MIPSEL-NEXT: move $3, $2 +; MIPSEL-NEXT: srav $4, $2, $10 +; MIPSEL-NEXT: seb $4, $4 +; MIPSEL-NEXT: or $1, $zero, $4 +; MIPSEL-NEXT: sllv $4, $4, $10 +; MIPSEL-NEXT: slt $5, $4, $7 +; MIPSEL-NEXT: move $3, $4 ; MIPSEL-NEXT: movz $3, $7, $5 ; MIPSEL-NEXT: and $3, $3, $8 ; MIPSEL-NEXT: and $4, $2, $9 @@ -3793,9 +3829,7 @@ define i8 @test_min_8(ptr nocapture %ptr, i8 signext %val) { ; MIPSEL-NEXT: beqz $4, $BB9_1 ; MIPSEL-NEXT: nop ; MIPSEL-NEXT: # %bb.2: # %entry -; MIPSEL-NEXT: and $1, $2, $8 -; MIPSEL-NEXT: srlv $1, $1, $10 -; MIPSEL-NEXT: seb $1, $1 +; MIPSEL-NEXT: .insn ; MIPSEL-NEXT: # %bb.3: # %entry ; MIPSEL-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MIPSEL-NEXT: # %bb.4: # %entry @@ -3822,12 +3856,12 @@ define i8 @test_min_8(ptr nocapture %ptr, i8 signext %val) { ; MIPSELR6-NEXT: $BB9_1: # %entry ; MIPSELR6-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPSELR6-NEXT: ll $2, 0($6) -; MIPSELR6-NEXT: srav $2, $2, $10 -; MIPSELR6-NEXT: srav $7, $7, $10 -; MIPSELR6-NEXT: seb $2, $2 -; MIPSELR6-NEXT: seb $7, $7 -; MIPSELR6-NEXT: slt $5, $2, $7 -; MIPSELR6-NEXT: selnez $3, $2, $5 +; MIPSELR6-NEXT: srav $4, $2, $10 +; MIPSELR6-NEXT: seb $4, $4 +; MIPSELR6-NEXT: or $1, $zero, $4 +; MIPSELR6-NEXT: sllv $4, $4, $10 +; MIPSELR6-NEXT: slt $5, $4, $7 +; MIPSELR6-NEXT: selnez $3, $4, $5 ; MIPSELR6-NEXT: seleqz $5, $7, $5 ; MIPSELR6-NEXT: or $3, $3, $5 ; MIPSELR6-NEXT: and $3, $3, $8 @@ -3835,10 +3869,9 @@ define i8 @test_min_8(ptr nocapture %ptr, i8 signext %val) { ; MIPSELR6-NEXT: or $4, $4, $3 ; MIPSELR6-NEXT: sc $4, 0($6) ; MIPSELR6-NEXT: beqzc $4, $BB9_1 +; MIPSELR6-NEXT: nop ; MIPSELR6-NEXT: # %bb.2: # %entry -; MIPSELR6-NEXT: and $1, $2, $8 -; MIPSELR6-NEXT: srlv $1, $1, $10 -; MIPSELR6-NEXT: seb $1, $1 +; MIPSELR6-NEXT: .insn ; MIPSELR6-NEXT: # %bb.3: # %entry ; MIPSELR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MIPSELR6-NEXT: # %bb.4: # %entry @@ -3864,12 +3897,12 @@ define i8 @test_min_8(ptr nocapture %ptr, i8 signext %val) { ; MMEL-NEXT: $BB9_1: # %entry ; MMEL-NEXT: # =>This Inner Loop Header: Depth=1 ; MMEL-NEXT: ll $2, 0($6) -; MMEL-NEXT: srav $2, $2, $10 -; MMEL-NEXT: srav $7, $7, $10 -; MMEL-NEXT: seb $2, $2 -; MMEL-NEXT: seb $7, $7 -; MMEL-NEXT: slt $5, $2, $7 -; MMEL-NEXT: or $3, $2, $zero +; MMEL-NEXT: srav $4, $2, $10 +; MMEL-NEXT: seb $4, $4 +; MMEL-NEXT: or $1, $zero, $4 +; MMEL-NEXT: sllv $4, $4, $10 +; MMEL-NEXT: slt $5, $4, $7 +; MMEL-NEXT: or $3, $4, $zero ; MMEL-NEXT: movz $3, $7, $5 ; MMEL-NEXT: and $3, $3, $8 ; MMEL-NEXT: and $4, $2, $9 @@ -3877,9 +3910,7 @@ define i8 @test_min_8(ptr nocapture %ptr, i8 signext %val) { ; MMEL-NEXT: sc $4, 0($6) ; MMEL-NEXT: beqzc $4, $BB9_1 ; MMEL-NEXT: # %bb.2: # %entry -; MMEL-NEXT: and $1, $2, $8 -; MMEL-NEXT: srlv $1, $1, $10 -; MMEL-NEXT: seb $1, $1 +; MMEL-NEXT: .insn ; MMEL-NEXT: # %bb.3: # %entry ; MMEL-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MMEL-NEXT: # %bb.4: # %entry @@ -3905,12 +3936,12 @@ define i8 @test_min_8(ptr nocapture %ptr, i8 signext %val) { ; MMELR6-NEXT: $BB9_1: # %entry ; MMELR6-NEXT: # =>This Inner Loop Header: Depth=1 ; MMELR6-NEXT: ll $2, 0($6) -; MMELR6-NEXT: srav $2, $2, $10 -; MMELR6-NEXT: srav $7, $7, $10 -; MMELR6-NEXT: seb $2, $2 -; MMELR6-NEXT: seb $7, $7 -; MMELR6-NEXT: slt $5, $2, $7 -; MMELR6-NEXT: selnez $3, $2, $5 +; MMELR6-NEXT: srav $4, $2, $10 +; MMELR6-NEXT: seb $4, $4 +; MMELR6-NEXT: or $1, $zero, $4 +; MMELR6-NEXT: sllv $4, $4, $10 +; MMELR6-NEXT: slt $5, $4, $7 +; MMELR6-NEXT: selnez $3, $4, $5 ; MMELR6-NEXT: seleqz $5, $7, $5 ; MMELR6-NEXT: or $3, $3, $5 ; MMELR6-NEXT: and $3, $3, $8 @@ -3919,9 +3950,7 @@ define i8 @test_min_8(ptr nocapture %ptr, i8 signext %val) { ; MMELR6-NEXT: sc $4, 0($6) ; MMELR6-NEXT: beqc $4, $zero, $BB9_1 ; MMELR6-NEXT: # %bb.2: # %entry -; MMELR6-NEXT: and $1, $2, $8 -; MMELR6-NEXT: srlv $1, $1, $10 -; MMELR6-NEXT: seb $1, $1 +; MMELR6-NEXT: .insn ; MMELR6-NEXT: # %bb.3: # %entry ; MMELR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MMELR6-NEXT: # %bb.4: # %entry @@ -3948,8 +3977,12 @@ define i8 @test_min_8(ptr nocapture %ptr, i8 signext %val) { ; MIPS64-NEXT: .LBB9_1: # %entry ; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPS64-NEXT: ll $2, 0($6) -; MIPS64-NEXT: slt $5, $2, $7 -; MIPS64-NEXT: move $3, $2 +; MIPS64-NEXT: srav $4, $2, $10 +; MIPS64-NEXT: seb $4, $4 +; MIPS64-NEXT: or $1, $zero, $4 +; MIPS64-NEXT: sllv $4, $4, $10 +; MIPS64-NEXT: slt $5, $4, $7 +; MIPS64-NEXT: move $3, $4 ; MIPS64-NEXT: movz $3, $7, $5 ; MIPS64-NEXT: and $3, $3, $8 ; MIPS64-NEXT: and $4, $2, $9 @@ -3958,9 +3991,7 @@ define i8 @test_min_8(ptr nocapture %ptr, i8 signext %val) { ; MIPS64-NEXT: beqz $4, .LBB9_1 ; MIPS64-NEXT: nop ; MIPS64-NEXT: # %bb.2: # %entry -; MIPS64-NEXT: and $1, $2, $8 -; MIPS64-NEXT: srlv $1, $1, $10 -; MIPS64-NEXT: seb $1, $1 +; MIPS64-NEXT: .insn ; MIPS64-NEXT: # %bb.3: # %entry ; MIPS64-NEXT: sw $1, 12($sp) # 4-byte Folded Spill ; MIPS64-NEXT: # %bb.4: # %entry @@ -3988,8 +4019,12 @@ define i8 @test_min_8(ptr nocapture %ptr, i8 signext %val) { ; MIPS64R6-NEXT: .LBB9_1: # %entry ; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPS64R6-NEXT: ll $2, 0($6) -; MIPS64R6-NEXT: slt $5, $2, $7 -; MIPS64R6-NEXT: selnez $3, $2, $5 +; MIPS64R6-NEXT: srav $4, $2, $10 +; MIPS64R6-NEXT: seb $4, $4 +; MIPS64R6-NEXT: or $1, $zero, $4 +; MIPS64R6-NEXT: sllv $4, $4, $10 +; MIPS64R6-NEXT: slt $5, $4, $7 +; MIPS64R6-NEXT: selnez $3, $4, $5 ; MIPS64R6-NEXT: seleqz $5, $7, $5 ; MIPS64R6-NEXT: or $3, $3, $5 ; MIPS64R6-NEXT: and $3, $3, $8 @@ -3997,10 +4032,9 @@ define i8 @test_min_8(ptr nocapture %ptr, i8 signext %val) { ; MIPS64R6-NEXT: or $4, $4, $3 ; MIPS64R6-NEXT: sc $4, 0($6) ; MIPS64R6-NEXT: beqzc $4, .LBB9_1 +; MIPS64R6-NEXT: nop ; MIPS64R6-NEXT: # %bb.2: # %entry -; MIPS64R6-NEXT: and $1, $2, $8 -; MIPS64R6-NEXT: srlv $1, $1, $10 -; MIPS64R6-NEXT: seb $1, $1 +; MIPS64R6-NEXT: .insn ; MIPS64R6-NEXT: # %bb.3: # %entry ; MIPS64R6-NEXT: sw $1, 12($sp) # 4-byte Folded Spill ; MIPS64R6-NEXT: # %bb.4: # %entry @@ -4026,12 +4060,12 @@ define i8 @test_min_8(ptr nocapture %ptr, i8 signext %val) { ; MIPS64EL-NEXT: .LBB9_1: # %entry ; MIPS64EL-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPS64EL-NEXT: ll $2, 0($6) -; MIPS64EL-NEXT: srav $2, $2, $10 -; MIPS64EL-NEXT: srav $7, $7, $10 -; MIPS64EL-NEXT: seb $2, $2 -; MIPS64EL-NEXT: seb $7, $7 -; MIPS64EL-NEXT: slt $5, $2, $7 -; MIPS64EL-NEXT: move $3, $2 +; MIPS64EL-NEXT: srav $4, $2, $10 +; MIPS64EL-NEXT: seb $4, $4 +; MIPS64EL-NEXT: or $1, $zero, $4 +; MIPS64EL-NEXT: sllv $4, $4, $10 +; MIPS64EL-NEXT: slt $5, $4, $7 +; MIPS64EL-NEXT: move $3, $4 ; MIPS64EL-NEXT: movz $3, $7, $5 ; MIPS64EL-NEXT: and $3, $3, $8 ; MIPS64EL-NEXT: and $4, $2, $9 @@ -4040,9 +4074,7 @@ define i8 @test_min_8(ptr nocapture %ptr, i8 signext %val) { ; MIPS64EL-NEXT: beqz $4, .LBB9_1 ; MIPS64EL-NEXT: nop ; MIPS64EL-NEXT: # %bb.2: # %entry -; MIPS64EL-NEXT: and $1, $2, $8 -; MIPS64EL-NEXT: srlv $1, $1, $10 -; MIPS64EL-NEXT: seb $1, $1 +; MIPS64EL-NEXT: .insn ; MIPS64EL-NEXT: # %bb.3: # %entry ; MIPS64EL-NEXT: sw $1, 12($sp) # 4-byte Folded Spill ; MIPS64EL-NEXT: # %bb.4: # %entry @@ -4069,12 +4101,12 @@ define i8 @test_min_8(ptr nocapture %ptr, i8 signext %val) { ; MIPS64ELR6-NEXT: .LBB9_1: # %entry ; MIPS64ELR6-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPS64ELR6-NEXT: ll $2, 0($6) -; MIPS64ELR6-NEXT: srav $2, $2, $10 -; MIPS64ELR6-NEXT: srav $7, $7, $10 -; MIPS64ELR6-NEXT: seb $2, $2 -; MIPS64ELR6-NEXT: seb $7, $7 -; MIPS64ELR6-NEXT: slt $5, $2, $7 -; MIPS64ELR6-NEXT: selnez $3, $2, $5 +; MIPS64ELR6-NEXT: srav $4, $2, $10 +; MIPS64ELR6-NEXT: seb $4, $4 +; MIPS64ELR6-NEXT: or $1, $zero, $4 +; MIPS64ELR6-NEXT: sllv $4, $4, $10 +; MIPS64ELR6-NEXT: slt $5, $4, $7 +; MIPS64ELR6-NEXT: selnez $3, $4, $5 ; MIPS64ELR6-NEXT: seleqz $5, $7, $5 ; MIPS64ELR6-NEXT: or $3, $3, $5 ; MIPS64ELR6-NEXT: and $3, $3, $8 @@ -4082,10 +4114,9 @@ define i8 @test_min_8(ptr nocapture %ptr, i8 signext %val) { ; MIPS64ELR6-NEXT: or $4, $4, $3 ; MIPS64ELR6-NEXT: sc $4, 0($6) ; MIPS64ELR6-NEXT: beqzc $4, .LBB9_1 +; MIPS64ELR6-NEXT: nop ; MIPS64ELR6-NEXT: # %bb.2: # %entry -; MIPS64ELR6-NEXT: and $1, $2, $8 -; MIPS64ELR6-NEXT: srlv $1, $1, $10 -; MIPS64ELR6-NEXT: seb $1, $1 +; MIPS64ELR6-NEXT: .insn ; MIPS64ELR6-NEXT: # %bb.3: # %entry ; MIPS64ELR6-NEXT: sw $1, 12($sp) # 4-byte Folded Spill ; MIPS64ELR6-NEXT: # %bb.4: # %entry @@ -4117,8 +4148,12 @@ define i8 @test_umax_8(ptr nocapture %ptr, i8 signext %val) { ; MIPS-NEXT: $BB10_1: # %entry ; MIPS-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPS-NEXT: ll $2, 0($6) -; MIPS-NEXT: sltu $5, $2, $7 -; MIPS-NEXT: move $3, $2 +; MIPS-NEXT: srav $4, $2, $10 +; MIPS-NEXT: andi $4, $4, 255 +; MIPS-NEXT: or $1, $zero, $4 +; MIPS-NEXT: sllv $4, $4, $10 +; MIPS-NEXT: sltu $5, $4, $7 +; MIPS-NEXT: move $3, $4 ; MIPS-NEXT: movn $3, $7, $5 ; MIPS-NEXT: and $3, $3, $8 ; MIPS-NEXT: and $4, $2, $9 @@ -4127,9 +4162,7 @@ define i8 @test_umax_8(ptr nocapture %ptr, i8 signext %val) { ; MIPS-NEXT: beqz $4, $BB10_1 ; MIPS-NEXT: nop ; MIPS-NEXT: # %bb.2: # %entry -; MIPS-NEXT: and $1, $2, $8 -; MIPS-NEXT: srlv $1, $1, $10 -; MIPS-NEXT: seh $1, $1 +; MIPS-NEXT: .insn ; MIPS-NEXT: # %bb.3: # %entry ; MIPS-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MIPS-NEXT: # %bb.4: # %entry @@ -4157,8 +4190,12 @@ define i8 @test_umax_8(ptr nocapture %ptr, i8 signext %val) { ; MIPSR6-NEXT: $BB10_1: # %entry ; MIPSR6-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPSR6-NEXT: ll $2, 0($6) -; MIPSR6-NEXT: sltu $5, $2, $7 -; MIPSR6-NEXT: seleqz $3, $2, $5 +; MIPSR6-NEXT: srav $4, $2, $10 +; MIPSR6-NEXT: andi $4, $4, 255 +; MIPSR6-NEXT: or $1, $zero, $4 +; MIPSR6-NEXT: sllv $4, $4, $10 +; MIPSR6-NEXT: sltu $5, $4, $7 +; MIPSR6-NEXT: seleqz $3, $4, $5 ; MIPSR6-NEXT: selnez $5, $7, $5 ; MIPSR6-NEXT: or $3, $3, $5 ; MIPSR6-NEXT: and $3, $3, $8 @@ -4166,10 +4203,9 @@ define i8 @test_umax_8(ptr nocapture %ptr, i8 signext %val) { ; MIPSR6-NEXT: or $4, $4, $3 ; MIPSR6-NEXT: sc $4, 0($6) ; MIPSR6-NEXT: beqzc $4, $BB10_1 +; MIPSR6-NEXT: nop ; MIPSR6-NEXT: # %bb.2: # %entry -; MIPSR6-NEXT: and $1, $2, $8 -; MIPSR6-NEXT: srlv $1, $1, $10 -; MIPSR6-NEXT: seh $1, $1 +; MIPSR6-NEXT: .insn ; MIPSR6-NEXT: # %bb.3: # %entry ; MIPSR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MIPSR6-NEXT: # %bb.4: # %entry @@ -4196,8 +4232,12 @@ define i8 @test_umax_8(ptr nocapture %ptr, i8 signext %val) { ; MM-NEXT: $BB10_1: # %entry ; MM-NEXT: # =>This Inner Loop Header: Depth=1 ; MM-NEXT: ll $2, 0($6) -; MM-NEXT: sltu $5, $2, $7 -; MM-NEXT: or $3, $2, $zero +; MM-NEXT: srav $4, $2, $10 +; MM-NEXT: andi $4, $4, 255 +; MM-NEXT: or $1, $zero, $4 +; MM-NEXT: sllv $4, $4, $10 +; MM-NEXT: sltu $5, $4, $7 +; MM-NEXT: or $3, $4, $zero ; MM-NEXT: movn $3, $7, $5 ; MM-NEXT: and $3, $3, $8 ; MM-NEXT: and $4, $2, $9 @@ -4205,9 +4245,7 @@ define i8 @test_umax_8(ptr nocapture %ptr, i8 signext %val) { ; MM-NEXT: sc $4, 0($6) ; MM-NEXT: beqzc $4, $BB10_1 ; MM-NEXT: # %bb.2: # %entry -; MM-NEXT: and $1, $2, $8 -; MM-NEXT: srlv $1, $1, $10 -; MM-NEXT: seh $1, $1 +; MM-NEXT: .insn ; MM-NEXT: # %bb.3: # %entry ; MM-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MM-NEXT: # %bb.4: # %entry @@ -4234,8 +4272,12 @@ define i8 @test_umax_8(ptr nocapture %ptr, i8 signext %val) { ; MMR6-NEXT: $BB10_1: # %entry ; MMR6-NEXT: # =>This Inner Loop Header: Depth=1 ; MMR6-NEXT: ll $2, 0($6) -; MMR6-NEXT: sltu $5, $2, $7 -; MMR6-NEXT: seleqz $3, $2, $5 +; MMR6-NEXT: srav $4, $2, $10 +; MMR6-NEXT: andi $4, $4, 255 +; MMR6-NEXT: or $1, $zero, $4 +; MMR6-NEXT: sllv $4, $4, $10 +; MMR6-NEXT: sltu $5, $4, $7 +; MMR6-NEXT: seleqz $3, $4, $5 ; MMR6-NEXT: selnez $5, $7, $5 ; MMR6-NEXT: or $3, $3, $5 ; MMR6-NEXT: and $3, $3, $8 @@ -4244,9 +4286,7 @@ define i8 @test_umax_8(ptr nocapture %ptr, i8 signext %val) { ; MMR6-NEXT: sc $4, 0($6) ; MMR6-NEXT: beqc $4, $zero, $BB10_1 ; MMR6-NEXT: # %bb.2: # %entry -; MMR6-NEXT: and $1, $2, $8 -; MMR6-NEXT: srlv $1, $1, $10 -; MMR6-NEXT: seh $1, $1 +; MMR6-NEXT: .insn ; MMR6-NEXT: # %bb.3: # %entry ; MMR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MMR6-NEXT: # %bb.4: # %entry @@ -4272,10 +4312,13 @@ define i8 @test_umax_8(ptr nocapture %ptr, i8 signext %val) { ; MIPS32-NEXT: $BB10_1: # %entry ; MIPS32-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPS32-NEXT: ll $2, 0($6) -; MIPS32-NEXT: and $2, $2, $8 -; MIPS32-NEXT: and $7, $7, $8 -; MIPS32-NEXT: sltu $5, $2, $7 -; MIPS32-NEXT: move $3, $2 +; MIPS32-NEXT: srav $4, $2, $10 +; MIPS32-NEXT: sll $4, $4, 24 +; MIPS32-NEXT: srl $4, $4, 24 +; MIPS32-NEXT: or $1, $zero, $4 +; MIPS32-NEXT: sllv $4, $4, $10 +; MIPS32-NEXT: sltu $5, $4, $7 +; MIPS32-NEXT: move $3, $4 ; MIPS32-NEXT: movn $3, $7, $5 ; MIPS32-NEXT: and $3, $3, $8 ; MIPS32-NEXT: and $4, $2, $9 @@ -4284,10 +4327,7 @@ define i8 @test_umax_8(ptr nocapture %ptr, i8 signext %val) { ; MIPS32-NEXT: beqz $4, $BB10_1 ; MIPS32-NEXT: nop ; MIPS32-NEXT: # %bb.2: # %entry -; MIPS32-NEXT: and $1, $2, $8 -; MIPS32-NEXT: srlv $1, $1, $10 -; MIPS32-NEXT: sll $1, $1, 16 -; MIPS32-NEXT: sra $1, $1, 16 +; MIPS32-NEXT: .insn ; MIPS32-NEXT: # %bb.3: # %entry ; MIPS32-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MIPS32-NEXT: # %bb.4: # %entry @@ -4314,10 +4354,12 @@ define i8 @test_umax_8(ptr nocapture %ptr, i8 signext %val) { ; MIPSEL-NEXT: $BB10_1: # %entry ; MIPSEL-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPSEL-NEXT: ll $2, 0($6) -; MIPSEL-NEXT: and $2, $2, $8 -; MIPSEL-NEXT: and $7, $7, $8 -; MIPSEL-NEXT: sltu $5, $2, $7 -; MIPSEL-NEXT: move $3, $2 +; MIPSEL-NEXT: srav $4, $2, $10 +; MIPSEL-NEXT: andi $4, $4, 255 +; MIPSEL-NEXT: or $1, $zero, $4 +; MIPSEL-NEXT: sllv $4, $4, $10 +; MIPSEL-NEXT: sltu $5, $4, $7 +; MIPSEL-NEXT: move $3, $4 ; MIPSEL-NEXT: movn $3, $7, $5 ; MIPSEL-NEXT: and $3, $3, $8 ; MIPSEL-NEXT: and $4, $2, $9 @@ -4326,9 +4368,7 @@ define i8 @test_umax_8(ptr nocapture %ptr, i8 signext %val) { ; MIPSEL-NEXT: beqz $4, $BB10_1 ; MIPSEL-NEXT: nop ; MIPSEL-NEXT: # %bb.2: # %entry -; MIPSEL-NEXT: and $1, $2, $8 -; MIPSEL-NEXT: srlv $1, $1, $10 -; MIPSEL-NEXT: seh $1, $1 +; MIPSEL-NEXT: .insn ; MIPSEL-NEXT: # %bb.3: # %entry ; MIPSEL-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MIPSEL-NEXT: # %bb.4: # %entry @@ -4355,10 +4395,12 @@ define i8 @test_umax_8(ptr nocapture %ptr, i8 signext %val) { ; MIPSELR6-NEXT: $BB10_1: # %entry ; MIPSELR6-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPSELR6-NEXT: ll $2, 0($6) -; MIPSELR6-NEXT: and $2, $2, $8 -; MIPSELR6-NEXT: and $7, $7, $8 -; MIPSELR6-NEXT: sltu $5, $2, $7 -; MIPSELR6-NEXT: seleqz $3, $2, $5 +; MIPSELR6-NEXT: srav $4, $2, $10 +; MIPSELR6-NEXT: andi $4, $4, 255 +; MIPSELR6-NEXT: or $1, $zero, $4 +; MIPSELR6-NEXT: sllv $4, $4, $10 +; MIPSELR6-NEXT: sltu $5, $4, $7 +; MIPSELR6-NEXT: seleqz $3, $4, $5 ; MIPSELR6-NEXT: selnez $5, $7, $5 ; MIPSELR6-NEXT: or $3, $3, $5 ; MIPSELR6-NEXT: and $3, $3, $8 @@ -4366,10 +4408,9 @@ define i8 @test_umax_8(ptr nocapture %ptr, i8 signext %val) { ; MIPSELR6-NEXT: or $4, $4, $3 ; MIPSELR6-NEXT: sc $4, 0($6) ; MIPSELR6-NEXT: beqzc $4, $BB10_1 +; MIPSELR6-NEXT: nop ; MIPSELR6-NEXT: # %bb.2: # %entry -; MIPSELR6-NEXT: and $1, $2, $8 -; MIPSELR6-NEXT: srlv $1, $1, $10 -; MIPSELR6-NEXT: seh $1, $1 +; MIPSELR6-NEXT: .insn ; MIPSELR6-NEXT: # %bb.3: # %entry ; MIPSELR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MIPSELR6-NEXT: # %bb.4: # %entry @@ -4395,10 +4436,12 @@ define i8 @test_umax_8(ptr nocapture %ptr, i8 signext %val) { ; MMEL-NEXT: $BB10_1: # %entry ; MMEL-NEXT: # =>This Inner Loop Header: Depth=1 ; MMEL-NEXT: ll $2, 0($6) -; MMEL-NEXT: and $2, $2, $8 -; MMEL-NEXT: and $7, $7, $8 -; MMEL-NEXT: sltu $5, $2, $7 -; MMEL-NEXT: or $3, $2, $zero +; MMEL-NEXT: srav $4, $2, $10 +; MMEL-NEXT: andi $4, $4, 255 +; MMEL-NEXT: or $1, $zero, $4 +; MMEL-NEXT: sllv $4, $4, $10 +; MMEL-NEXT: sltu $5, $4, $7 +; MMEL-NEXT: or $3, $4, $zero ; MMEL-NEXT: movn $3, $7, $5 ; MMEL-NEXT: and $3, $3, $8 ; MMEL-NEXT: and $4, $2, $9 @@ -4406,9 +4449,7 @@ define i8 @test_umax_8(ptr nocapture %ptr, i8 signext %val) { ; MMEL-NEXT: sc $4, 0($6) ; MMEL-NEXT: beqzc $4, $BB10_1 ; MMEL-NEXT: # %bb.2: # %entry -; MMEL-NEXT: and $1, $2, $8 -; MMEL-NEXT: srlv $1, $1, $10 -; MMEL-NEXT: seh $1, $1 +; MMEL-NEXT: .insn ; MMEL-NEXT: # %bb.3: # %entry ; MMEL-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MMEL-NEXT: # %bb.4: # %entry @@ -4434,10 +4475,12 @@ define i8 @test_umax_8(ptr nocapture %ptr, i8 signext %val) { ; MMELR6-NEXT: $BB10_1: # %entry ; MMELR6-NEXT: # =>This Inner Loop Header: Depth=1 ; MMELR6-NEXT: ll $2, 0($6) -; MMELR6-NEXT: and $2, $2, $8 -; MMELR6-NEXT: and $7, $7, $8 -; MMELR6-NEXT: sltu $5, $2, $7 -; MMELR6-NEXT: seleqz $3, $2, $5 +; MMELR6-NEXT: srav $4, $2, $10 +; MMELR6-NEXT: andi $4, $4, 255 +; MMELR6-NEXT: or $1, $zero, $4 +; MMELR6-NEXT: sllv $4, $4, $10 +; MMELR6-NEXT: sltu $5, $4, $7 +; MMELR6-NEXT: seleqz $3, $4, $5 ; MMELR6-NEXT: selnez $5, $7, $5 ; MMELR6-NEXT: or $3, $3, $5 ; MMELR6-NEXT: and $3, $3, $8 @@ -4446,9 +4489,7 @@ define i8 @test_umax_8(ptr nocapture %ptr, i8 signext %val) { ; MMELR6-NEXT: sc $4, 0($6) ; MMELR6-NEXT: beqc $4, $zero, $BB10_1 ; MMELR6-NEXT: # %bb.2: # %entry -; MMELR6-NEXT: and $1, $2, $8 -; MMELR6-NEXT: srlv $1, $1, $10 -; MMELR6-NEXT: seh $1, $1 +; MMELR6-NEXT: .insn ; MMELR6-NEXT: # %bb.3: # %entry ; MMELR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MMELR6-NEXT: # %bb.4: # %entry @@ -4475,8 +4516,12 @@ define i8 @test_umax_8(ptr nocapture %ptr, i8 signext %val) { ; MIPS64-NEXT: .LBB10_1: # %entry ; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPS64-NEXT: ll $2, 0($6) -; MIPS64-NEXT: sltu $5, $2, $7 -; MIPS64-NEXT: move $3, $2 +; MIPS64-NEXT: srav $4, $2, $10 +; MIPS64-NEXT: andi $4, $4, 255 +; MIPS64-NEXT: or $1, $zero, $4 +; MIPS64-NEXT: sllv $4, $4, $10 +; MIPS64-NEXT: sltu $5, $4, $7 +; MIPS64-NEXT: move $3, $4 ; MIPS64-NEXT: movn $3, $7, $5 ; MIPS64-NEXT: and $3, $3, $8 ; MIPS64-NEXT: and $4, $2, $9 @@ -4485,9 +4530,7 @@ define i8 @test_umax_8(ptr nocapture %ptr, i8 signext %val) { ; MIPS64-NEXT: beqz $4, .LBB10_1 ; MIPS64-NEXT: nop ; MIPS64-NEXT: # %bb.2: # %entry -; MIPS64-NEXT: and $1, $2, $8 -; MIPS64-NEXT: srlv $1, $1, $10 -; MIPS64-NEXT: seh $1, $1 +; MIPS64-NEXT: .insn ; MIPS64-NEXT: # %bb.3: # %entry ; MIPS64-NEXT: sw $1, 12($sp) # 4-byte Folded Spill ; MIPS64-NEXT: # %bb.4: # %entry @@ -4515,8 +4558,12 @@ define i8 @test_umax_8(ptr nocapture %ptr, i8 signext %val) { ; MIPS64R6-NEXT: .LBB10_1: # %entry ; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPS64R6-NEXT: ll $2, 0($6) -; MIPS64R6-NEXT: sltu $5, $2, $7 -; MIPS64R6-NEXT: seleqz $3, $2, $5 +; MIPS64R6-NEXT: srav $4, $2, $10 +; MIPS64R6-NEXT: andi $4, $4, 255 +; MIPS64R6-NEXT: or $1, $zero, $4 +; MIPS64R6-NEXT: sllv $4, $4, $10 +; MIPS64R6-NEXT: sltu $5, $4, $7 +; MIPS64R6-NEXT: seleqz $3, $4, $5 ; MIPS64R6-NEXT: selnez $5, $7, $5 ; MIPS64R6-NEXT: or $3, $3, $5 ; MIPS64R6-NEXT: and $3, $3, $8 @@ -4524,10 +4571,9 @@ define i8 @test_umax_8(ptr nocapture %ptr, i8 signext %val) { ; MIPS64R6-NEXT: or $4, $4, $3 ; MIPS64R6-NEXT: sc $4, 0($6) ; MIPS64R6-NEXT: beqzc $4, .LBB10_1 +; MIPS64R6-NEXT: nop ; MIPS64R6-NEXT: # %bb.2: # %entry -; MIPS64R6-NEXT: and $1, $2, $8 -; MIPS64R6-NEXT: srlv $1, $1, $10 -; MIPS64R6-NEXT: seh $1, $1 +; MIPS64R6-NEXT: .insn ; MIPS64R6-NEXT: # %bb.3: # %entry ; MIPS64R6-NEXT: sw $1, 12($sp) # 4-byte Folded Spill ; MIPS64R6-NEXT: # %bb.4: # %entry @@ -4553,10 +4599,12 @@ define i8 @test_umax_8(ptr nocapture %ptr, i8 signext %val) { ; MIPS64EL-NEXT: .LBB10_1: # %entry ; MIPS64EL-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPS64EL-NEXT: ll $2, 0($6) -; MIPS64EL-NEXT: and $2, $2, $8 -; MIPS64EL-NEXT: and $7, $7, $8 -; MIPS64EL-NEXT: sltu $5, $2, $7 -; MIPS64EL-NEXT: move $3, $2 +; MIPS64EL-NEXT: srav $4, $2, $10 +; MIPS64EL-NEXT: andi $4, $4, 255 +; MIPS64EL-NEXT: or $1, $zero, $4 +; MIPS64EL-NEXT: sllv $4, $4, $10 +; MIPS64EL-NEXT: sltu $5, $4, $7 +; MIPS64EL-NEXT: move $3, $4 ; MIPS64EL-NEXT: movn $3, $7, $5 ; MIPS64EL-NEXT: and $3, $3, $8 ; MIPS64EL-NEXT: and $4, $2, $9 @@ -4565,9 +4613,7 @@ define i8 @test_umax_8(ptr nocapture %ptr, i8 signext %val) { ; MIPS64EL-NEXT: beqz $4, .LBB10_1 ; MIPS64EL-NEXT: nop ; MIPS64EL-NEXT: # %bb.2: # %entry -; MIPS64EL-NEXT: and $1, $2, $8 -; MIPS64EL-NEXT: srlv $1, $1, $10 -; MIPS64EL-NEXT: seh $1, $1 +; MIPS64EL-NEXT: .insn ; MIPS64EL-NEXT: # %bb.3: # %entry ; MIPS64EL-NEXT: sw $1, 12($sp) # 4-byte Folded Spill ; MIPS64EL-NEXT: # %bb.4: # %entry @@ -4594,10 +4640,12 @@ define i8 @test_umax_8(ptr nocapture %ptr, i8 signext %val) { ; MIPS64ELR6-NEXT: .LBB10_1: # %entry ; MIPS64ELR6-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPS64ELR6-NEXT: ll $2, 0($6) -; MIPS64ELR6-NEXT: and $2, $2, $8 -; MIPS64ELR6-NEXT: and $7, $7, $8 -; MIPS64ELR6-NEXT: sltu $5, $2, $7 -; MIPS64ELR6-NEXT: seleqz $3, $2, $5 +; MIPS64ELR6-NEXT: srav $4, $2, $10 +; MIPS64ELR6-NEXT: andi $4, $4, 255 +; MIPS64ELR6-NEXT: or $1, $zero, $4 +; MIPS64ELR6-NEXT: sllv $4, $4, $10 +; MIPS64ELR6-NEXT: sltu $5, $4, $7 +; MIPS64ELR6-NEXT: seleqz $3, $4, $5 ; MIPS64ELR6-NEXT: selnez $5, $7, $5 ; MIPS64ELR6-NEXT: or $3, $3, $5 ; MIPS64ELR6-NEXT: and $3, $3, $8 @@ -4605,10 +4653,9 @@ define i8 @test_umax_8(ptr nocapture %ptr, i8 signext %val) { ; MIPS64ELR6-NEXT: or $4, $4, $3 ; MIPS64ELR6-NEXT: sc $4, 0($6) ; MIPS64ELR6-NEXT: beqzc $4, .LBB10_1 +; MIPS64ELR6-NEXT: nop ; MIPS64ELR6-NEXT: # %bb.2: # %entry -; MIPS64ELR6-NEXT: and $1, $2, $8 -; MIPS64ELR6-NEXT: srlv $1, $1, $10 -; MIPS64ELR6-NEXT: seh $1, $1 +; MIPS64ELR6-NEXT: .insn ; MIPS64ELR6-NEXT: # %bb.3: # %entry ; MIPS64ELR6-NEXT: sw $1, 12($sp) # 4-byte Folded Spill ; MIPS64ELR6-NEXT: # %bb.4: # %entry @@ -4640,8 +4687,12 @@ define i8 @test_umin_8(ptr nocapture %ptr, i8 signext %val) { ; MIPS-NEXT: $BB11_1: # %entry ; MIPS-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPS-NEXT: ll $2, 0($6) -; MIPS-NEXT: sltu $5, $2, $7 -; MIPS-NEXT: move $3, $2 +; MIPS-NEXT: srav $4, $2, $10 +; MIPS-NEXT: andi $4, $4, 255 +; MIPS-NEXT: or $1, $zero, $4 +; MIPS-NEXT: sllv $4, $4, $10 +; MIPS-NEXT: sltu $5, $4, $7 +; MIPS-NEXT: move $3, $4 ; MIPS-NEXT: movz $3, $7, $5 ; MIPS-NEXT: and $3, $3, $8 ; MIPS-NEXT: and $4, $2, $9 @@ -4650,9 +4701,7 @@ define i8 @test_umin_8(ptr nocapture %ptr, i8 signext %val) { ; MIPS-NEXT: beqz $4, $BB11_1 ; MIPS-NEXT: nop ; MIPS-NEXT: # %bb.2: # %entry -; MIPS-NEXT: and $1, $2, $8 -; MIPS-NEXT: srlv $1, $1, $10 -; MIPS-NEXT: seh $1, $1 +; MIPS-NEXT: .insn ; MIPS-NEXT: # %bb.3: # %entry ; MIPS-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MIPS-NEXT: # %bb.4: # %entry @@ -4680,8 +4729,12 @@ define i8 @test_umin_8(ptr nocapture %ptr, i8 signext %val) { ; MIPSR6-NEXT: $BB11_1: # %entry ; MIPSR6-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPSR6-NEXT: ll $2, 0($6) -; MIPSR6-NEXT: sltu $5, $2, $7 -; MIPSR6-NEXT: selnez $3, $2, $5 +; MIPSR6-NEXT: srav $4, $2, $10 +; MIPSR6-NEXT: andi $4, $4, 255 +; MIPSR6-NEXT: or $1, $zero, $4 +; MIPSR6-NEXT: sllv $4, $4, $10 +; MIPSR6-NEXT: sltu $5, $4, $7 +; MIPSR6-NEXT: selnez $3, $4, $5 ; MIPSR6-NEXT: seleqz $5, $7, $5 ; MIPSR6-NEXT: or $3, $3, $5 ; MIPSR6-NEXT: and $3, $3, $8 @@ -4689,10 +4742,9 @@ define i8 @test_umin_8(ptr nocapture %ptr, i8 signext %val) { ; MIPSR6-NEXT: or $4, $4, $3 ; MIPSR6-NEXT: sc $4, 0($6) ; MIPSR6-NEXT: beqzc $4, $BB11_1 +; MIPSR6-NEXT: nop ; MIPSR6-NEXT: # %bb.2: # %entry -; MIPSR6-NEXT: and $1, $2, $8 -; MIPSR6-NEXT: srlv $1, $1, $10 -; MIPSR6-NEXT: seh $1, $1 +; MIPSR6-NEXT: .insn ; MIPSR6-NEXT: # %bb.3: # %entry ; MIPSR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MIPSR6-NEXT: # %bb.4: # %entry @@ -4719,8 +4771,12 @@ define i8 @test_umin_8(ptr nocapture %ptr, i8 signext %val) { ; MM-NEXT: $BB11_1: # %entry ; MM-NEXT: # =>This Inner Loop Header: Depth=1 ; MM-NEXT: ll $2, 0($6) -; MM-NEXT: sltu $5, $2, $7 -; MM-NEXT: or $3, $2, $zero +; MM-NEXT: srav $4, $2, $10 +; MM-NEXT: andi $4, $4, 255 +; MM-NEXT: or $1, $zero, $4 +; MM-NEXT: sllv $4, $4, $10 +; MM-NEXT: sltu $5, $4, $7 +; MM-NEXT: or $3, $4, $zero ; MM-NEXT: movz $3, $7, $5 ; MM-NEXT: and $3, $3, $8 ; MM-NEXT: and $4, $2, $9 @@ -4728,9 +4784,7 @@ define i8 @test_umin_8(ptr nocapture %ptr, i8 signext %val) { ; MM-NEXT: sc $4, 0($6) ; MM-NEXT: beqzc $4, $BB11_1 ; MM-NEXT: # %bb.2: # %entry -; MM-NEXT: and $1, $2, $8 -; MM-NEXT: srlv $1, $1, $10 -; MM-NEXT: seh $1, $1 +; MM-NEXT: .insn ; MM-NEXT: # %bb.3: # %entry ; MM-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MM-NEXT: # %bb.4: # %entry @@ -4757,8 +4811,12 @@ define i8 @test_umin_8(ptr nocapture %ptr, i8 signext %val) { ; MMR6-NEXT: $BB11_1: # %entry ; MMR6-NEXT: # =>This Inner Loop Header: Depth=1 ; MMR6-NEXT: ll $2, 0($6) -; MMR6-NEXT: sltu $5, $2, $7 -; MMR6-NEXT: selnez $3, $2, $5 +; MMR6-NEXT: srav $4, $2, $10 +; MMR6-NEXT: andi $4, $4, 255 +; MMR6-NEXT: or $1, $zero, $4 +; MMR6-NEXT: sllv $4, $4, $10 +; MMR6-NEXT: sltu $5, $4, $7 +; MMR6-NEXT: selnez $3, $4, $5 ; MMR6-NEXT: seleqz $5, $7, $5 ; MMR6-NEXT: or $3, $3, $5 ; MMR6-NEXT: and $3, $3, $8 @@ -4767,9 +4825,7 @@ define i8 @test_umin_8(ptr nocapture %ptr, i8 signext %val) { ; MMR6-NEXT: sc $4, 0($6) ; MMR6-NEXT: beqc $4, $zero, $BB11_1 ; MMR6-NEXT: # %bb.2: # %entry -; MMR6-NEXT: and $1, $2, $8 -; MMR6-NEXT: srlv $1, $1, $10 -; MMR6-NEXT: seh $1, $1 +; MMR6-NEXT: .insn ; MMR6-NEXT: # %bb.3: # %entry ; MMR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MMR6-NEXT: # %bb.4: # %entry @@ -4795,10 +4851,13 @@ define i8 @test_umin_8(ptr nocapture %ptr, i8 signext %val) { ; MIPS32-NEXT: $BB11_1: # %entry ; MIPS32-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPS32-NEXT: ll $2, 0($6) -; MIPS32-NEXT: and $2, $2, $8 -; MIPS32-NEXT: and $7, $7, $8 -; MIPS32-NEXT: sltu $5, $2, $7 -; MIPS32-NEXT: move $3, $2 +; MIPS32-NEXT: srav $4, $2, $10 +; MIPS32-NEXT: sll $4, $4, 24 +; MIPS32-NEXT: srl $4, $4, 24 +; MIPS32-NEXT: or $1, $zero, $4 +; MIPS32-NEXT: sllv $4, $4, $10 +; MIPS32-NEXT: sltu $5, $4, $7 +; MIPS32-NEXT: move $3, $4 ; MIPS32-NEXT: movz $3, $7, $5 ; MIPS32-NEXT: and $3, $3, $8 ; MIPS32-NEXT: and $4, $2, $9 @@ -4807,10 +4866,7 @@ define i8 @test_umin_8(ptr nocapture %ptr, i8 signext %val) { ; MIPS32-NEXT: beqz $4, $BB11_1 ; MIPS32-NEXT: nop ; MIPS32-NEXT: # %bb.2: # %entry -; MIPS32-NEXT: and $1, $2, $8 -; MIPS32-NEXT: srlv $1, $1, $10 -; MIPS32-NEXT: sll $1, $1, 16 -; MIPS32-NEXT: sra $1, $1, 16 +; MIPS32-NEXT: .insn ; MIPS32-NEXT: # %bb.3: # %entry ; MIPS32-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MIPS32-NEXT: # %bb.4: # %entry @@ -4837,10 +4893,12 @@ define i8 @test_umin_8(ptr nocapture %ptr, i8 signext %val) { ; MIPSEL-NEXT: $BB11_1: # %entry ; MIPSEL-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPSEL-NEXT: ll $2, 0($6) -; MIPSEL-NEXT: and $2, $2, $8 -; MIPSEL-NEXT: and $7, $7, $8 -; MIPSEL-NEXT: sltu $5, $2, $7 -; MIPSEL-NEXT: move $3, $2 +; MIPSEL-NEXT: srav $4, $2, $10 +; MIPSEL-NEXT: andi $4, $4, 255 +; MIPSEL-NEXT: or $1, $zero, $4 +; MIPSEL-NEXT: sllv $4, $4, $10 +; MIPSEL-NEXT: sltu $5, $4, $7 +; MIPSEL-NEXT: move $3, $4 ; MIPSEL-NEXT: movz $3, $7, $5 ; MIPSEL-NEXT: and $3, $3, $8 ; MIPSEL-NEXT: and $4, $2, $9 @@ -4849,9 +4907,7 @@ define i8 @test_umin_8(ptr nocapture %ptr, i8 signext %val) { ; MIPSEL-NEXT: beqz $4, $BB11_1 ; MIPSEL-NEXT: nop ; MIPSEL-NEXT: # %bb.2: # %entry -; MIPSEL-NEXT: and $1, $2, $8 -; MIPSEL-NEXT: srlv $1, $1, $10 -; MIPSEL-NEXT: seh $1, $1 +; MIPSEL-NEXT: .insn ; MIPSEL-NEXT: # %bb.3: # %entry ; MIPSEL-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MIPSEL-NEXT: # %bb.4: # %entry @@ -4878,10 +4934,12 @@ define i8 @test_umin_8(ptr nocapture %ptr, i8 signext %val) { ; MIPSELR6-NEXT: $BB11_1: # %entry ; MIPSELR6-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPSELR6-NEXT: ll $2, 0($6) -; MIPSELR6-NEXT: and $2, $2, $8 -; MIPSELR6-NEXT: and $7, $7, $8 -; MIPSELR6-NEXT: sltu $5, $2, $7 -; MIPSELR6-NEXT: selnez $3, $2, $5 +; MIPSELR6-NEXT: srav $4, $2, $10 +; MIPSELR6-NEXT: andi $4, $4, 255 +; MIPSELR6-NEXT: or $1, $zero, $4 +; MIPSELR6-NEXT: sllv $4, $4, $10 +; MIPSELR6-NEXT: sltu $5, $4, $7 +; MIPSELR6-NEXT: selnez $3, $4, $5 ; MIPSELR6-NEXT: seleqz $5, $7, $5 ; MIPSELR6-NEXT: or $3, $3, $5 ; MIPSELR6-NEXT: and $3, $3, $8 @@ -4889,10 +4947,9 @@ define i8 @test_umin_8(ptr nocapture %ptr, i8 signext %val) { ; MIPSELR6-NEXT: or $4, $4, $3 ; MIPSELR6-NEXT: sc $4, 0($6) ; MIPSELR6-NEXT: beqzc $4, $BB11_1 +; MIPSELR6-NEXT: nop ; MIPSELR6-NEXT: # %bb.2: # %entry -; MIPSELR6-NEXT: and $1, $2, $8 -; MIPSELR6-NEXT: srlv $1, $1, $10 -; MIPSELR6-NEXT: seh $1, $1 +; MIPSELR6-NEXT: .insn ; MIPSELR6-NEXT: # %bb.3: # %entry ; MIPSELR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MIPSELR6-NEXT: # %bb.4: # %entry @@ -4918,10 +4975,12 @@ define i8 @test_umin_8(ptr nocapture %ptr, i8 signext %val) { ; MMEL-NEXT: $BB11_1: # %entry ; MMEL-NEXT: # =>This Inner Loop Header: Depth=1 ; MMEL-NEXT: ll $2, 0($6) -; MMEL-NEXT: and $2, $2, $8 -; MMEL-NEXT: and $7, $7, $8 -; MMEL-NEXT: sltu $5, $2, $7 -; MMEL-NEXT: or $3, $2, $zero +; MMEL-NEXT: srav $4, $2, $10 +; MMEL-NEXT: andi $4, $4, 255 +; MMEL-NEXT: or $1, $zero, $4 +; MMEL-NEXT: sllv $4, $4, $10 +; MMEL-NEXT: sltu $5, $4, $7 +; MMEL-NEXT: or $3, $4, $zero ; MMEL-NEXT: movz $3, $7, $5 ; MMEL-NEXT: and $3, $3, $8 ; MMEL-NEXT: and $4, $2, $9 @@ -4929,9 +4988,7 @@ define i8 @test_umin_8(ptr nocapture %ptr, i8 signext %val) { ; MMEL-NEXT: sc $4, 0($6) ; MMEL-NEXT: beqzc $4, $BB11_1 ; MMEL-NEXT: # %bb.2: # %entry -; MMEL-NEXT: and $1, $2, $8 -; MMEL-NEXT: srlv $1, $1, $10 -; MMEL-NEXT: seh $1, $1 +; MMEL-NEXT: .insn ; MMEL-NEXT: # %bb.3: # %entry ; MMEL-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MMEL-NEXT: # %bb.4: # %entry @@ -4957,10 +5014,12 @@ define i8 @test_umin_8(ptr nocapture %ptr, i8 signext %val) { ; MMELR6-NEXT: $BB11_1: # %entry ; MMELR6-NEXT: # =>This Inner Loop Header: Depth=1 ; MMELR6-NEXT: ll $2, 0($6) -; MMELR6-NEXT: and $2, $2, $8 -; MMELR6-NEXT: and $7, $7, $8 -; MMELR6-NEXT: sltu $5, $2, $7 -; MMELR6-NEXT: selnez $3, $2, $5 +; MMELR6-NEXT: srav $4, $2, $10 +; MMELR6-NEXT: andi $4, $4, 255 +; MMELR6-NEXT: or $1, $zero, $4 +; MMELR6-NEXT: sllv $4, $4, $10 +; MMELR6-NEXT: sltu $5, $4, $7 +; MMELR6-NEXT: selnez $3, $4, $5 ; MMELR6-NEXT: seleqz $5, $7, $5 ; MMELR6-NEXT: or $3, $3, $5 ; MMELR6-NEXT: and $3, $3, $8 @@ -4969,9 +5028,7 @@ define i8 @test_umin_8(ptr nocapture %ptr, i8 signext %val) { ; MMELR6-NEXT: sc $4, 0($6) ; MMELR6-NEXT: beqc $4, $zero, $BB11_1 ; MMELR6-NEXT: # %bb.2: # %entry -; MMELR6-NEXT: and $1, $2, $8 -; MMELR6-NEXT: srlv $1, $1, $10 -; MMELR6-NEXT: seh $1, $1 +; MMELR6-NEXT: .insn ; MMELR6-NEXT: # %bb.3: # %entry ; MMELR6-NEXT: sw $1, 4($sp) # 4-byte Folded Spill ; MMELR6-NEXT: # %bb.4: # %entry @@ -4998,8 +5055,12 @@ define i8 @test_umin_8(ptr nocapture %ptr, i8 signext %val) { ; MIPS64-NEXT: .LBB11_1: # %entry ; MIPS64-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPS64-NEXT: ll $2, 0($6) -; MIPS64-NEXT: sltu $5, $2, $7 -; MIPS64-NEXT: move $3, $2 +; MIPS64-NEXT: srav $4, $2, $10 +; MIPS64-NEXT: andi $4, $4, 255 +; MIPS64-NEXT: or $1, $zero, $4 +; MIPS64-NEXT: sllv $4, $4, $10 +; MIPS64-NEXT: sltu $5, $4, $7 +; MIPS64-NEXT: move $3, $4 ; MIPS64-NEXT: movz $3, $7, $5 ; MIPS64-NEXT: and $3, $3, $8 ; MIPS64-NEXT: and $4, $2, $9 @@ -5008,9 +5069,7 @@ define i8 @test_umin_8(ptr nocapture %ptr, i8 signext %val) { ; MIPS64-NEXT: beqz $4, .LBB11_1 ; MIPS64-NEXT: nop ; MIPS64-NEXT: # %bb.2: # %entry -; MIPS64-NEXT: and $1, $2, $8 -; MIPS64-NEXT: srlv $1, $1, $10 -; MIPS64-NEXT: seh $1, $1 +; MIPS64-NEXT: .insn ; MIPS64-NEXT: # %bb.3: # %entry ; MIPS64-NEXT: sw $1, 12($sp) # 4-byte Folded Spill ; MIPS64-NEXT: # %bb.4: # %entry @@ -5038,8 +5097,12 @@ define i8 @test_umin_8(ptr nocapture %ptr, i8 signext %val) { ; MIPS64R6-NEXT: .LBB11_1: # %entry ; MIPS64R6-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPS64R6-NEXT: ll $2, 0($6) -; MIPS64R6-NEXT: sltu $5, $2, $7 -; MIPS64R6-NEXT: selnez $3, $2, $5 +; MIPS64R6-NEXT: srav $4, $2, $10 +; MIPS64R6-NEXT: andi $4, $4, 255 +; MIPS64R6-NEXT: or $1, $zero, $4 +; MIPS64R6-NEXT: sllv $4, $4, $10 +; MIPS64R6-NEXT: sltu $5, $4, $7 +; MIPS64R6-NEXT: selnez $3, $4, $5 ; MIPS64R6-NEXT: seleqz $5, $7, $5 ; MIPS64R6-NEXT: or $3, $3, $5 ; MIPS64R6-NEXT: and $3, $3, $8 @@ -5047,10 +5110,9 @@ define i8 @test_umin_8(ptr nocapture %ptr, i8 signext %val) { ; MIPS64R6-NEXT: or $4, $4, $3 ; MIPS64R6-NEXT: sc $4, 0($6) ; MIPS64R6-NEXT: beqzc $4, .LBB11_1 +; MIPS64R6-NEXT: nop ; MIPS64R6-NEXT: # %bb.2: # %entry -; MIPS64R6-NEXT: and $1, $2, $8 -; MIPS64R6-NEXT: srlv $1, $1, $10 -; MIPS64R6-NEXT: seh $1, $1 +; MIPS64R6-NEXT: .insn ; MIPS64R6-NEXT: # %bb.3: # %entry ; MIPS64R6-NEXT: sw $1, 12($sp) # 4-byte Folded Spill ; MIPS64R6-NEXT: # %bb.4: # %entry @@ -5076,10 +5138,12 @@ define i8 @test_umin_8(ptr nocapture %ptr, i8 signext %val) { ; MIPS64EL-NEXT: .LBB11_1: # %entry ; MIPS64EL-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPS64EL-NEXT: ll $2, 0($6) -; MIPS64EL-NEXT: and $2, $2, $8 -; MIPS64EL-NEXT: and $7, $7, $8 -; MIPS64EL-NEXT: sltu $5, $2, $7 -; MIPS64EL-NEXT: move $3, $2 +; MIPS64EL-NEXT: srav $4, $2, $10 +; MIPS64EL-NEXT: andi $4, $4, 255 +; MIPS64EL-NEXT: or $1, $zero, $4 +; MIPS64EL-NEXT: sllv $4, $4, $10 +; MIPS64EL-NEXT: sltu $5, $4, $7 +; MIPS64EL-NEXT: move $3, $4 ; MIPS64EL-NEXT: movz $3, $7, $5 ; MIPS64EL-NEXT: and $3, $3, $8 ; MIPS64EL-NEXT: and $4, $2, $9 @@ -5088,9 +5152,7 @@ define i8 @test_umin_8(ptr nocapture %ptr, i8 signext %val) { ; MIPS64EL-NEXT: beqz $4, .LBB11_1 ; MIPS64EL-NEXT: nop ; MIPS64EL-NEXT: # %bb.2: # %entry -; MIPS64EL-NEXT: and $1, $2, $8 -; MIPS64EL-NEXT: srlv $1, $1, $10 -; MIPS64EL-NEXT: seh $1, $1 +; MIPS64EL-NEXT: .insn ; MIPS64EL-NEXT: # %bb.3: # %entry ; MIPS64EL-NEXT: sw $1, 12($sp) # 4-byte Folded Spill ; MIPS64EL-NEXT: # %bb.4: # %entry @@ -5117,10 +5179,12 @@ define i8 @test_umin_8(ptr nocapture %ptr, i8 signext %val) { ; MIPS64ELR6-NEXT: .LBB11_1: # %entry ; MIPS64ELR6-NEXT: # =>This Inner Loop Header: Depth=1 ; MIPS64ELR6-NEXT: ll $2, 0($6) -; MIPS64ELR6-NEXT: and $2, $2, $8 -; MIPS64ELR6-NEXT: and $7, $7, $8 -; MIPS64ELR6-NEXT: sltu $5, $2, $7 -; MIPS64ELR6-NEXT: selnez $3, $2, $5 +; MIPS64ELR6-NEXT: srav $4, $2, $10 +; MIPS64ELR6-NEXT: andi $4, $4, 255 +; MIPS64ELR6-NEXT: or $1, $zero, $4 +; MIPS64ELR6-NEXT: sllv $4, $4, $10 +; MIPS64ELR6-NEXT: sltu $5, $4, $7 +; MIPS64ELR6-NEXT: selnez $3, $4, $5 ; MIPS64ELR6-NEXT: seleqz $5, $7, $5 ; MIPS64ELR6-NEXT: or $3, $3, $5 ; MIPS64ELR6-NEXT: and $3, $3, $8 @@ -5128,10 +5192,9 @@ define i8 @test_umin_8(ptr nocapture %ptr, i8 signext %val) { ; MIPS64ELR6-NEXT: or $4, $4, $3 ; MIPS64ELR6-NEXT: sc $4, 0($6) ; MIPS64ELR6-NEXT: beqzc $4, .LBB11_1 +; MIPS64ELR6-NEXT: nop ; MIPS64ELR6-NEXT: # %bb.2: # %entry -; MIPS64ELR6-NEXT: and $1, $2, $8 -; MIPS64ELR6-NEXT: srlv $1, $1, $10 -; MIPS64ELR6-NEXT: seh $1, $1 +; MIPS64ELR6-NEXT: .insn ; MIPS64ELR6-NEXT: # %bb.3: # %entry ; MIPS64ELR6-NEXT: sw $1, 12($sp) # 4-byte Folded Spill ; MIPS64ELR6-NEXT: # %bb.4: # %entry -- GitLab From 2834e8ad1cfe32b69a8b5a1dd2477725683a61c4 Mon Sep 17 00:00:00 2001 From: Jordan Rupprecht Date: Mon, 22 Apr 2024 13:32:40 -0500 Subject: [PATCH 017/732] [lldb][NFC] Remove unused pexpect/ptyprocess (#89609) --- .../Python/module/pexpect-4.6/.gitignore | 11 - .../Python/module/pexpect-4.6/.travis.yml | 31 - .../Python/module/pexpect-4.6/DEVELOPERS.rst | 12 - .../Python/module/pexpect-4.6/LICENSE | 20 - .../Python/module/pexpect-4.6/MANIFEST.in | 6 - .../Python/module/pexpect-4.6/README.rst | 55 -- .../Python/module/pexpect-4.6/pexpect/ANSI.py | 351 -------- .../Python/module/pexpect-4.6/pexpect/FSM.py | 334 ------- .../module/pexpect-4.6/pexpect/__init__.py | 85 -- .../module/pexpect-4.6/pexpect/_async.py | 87 -- .../module/pexpect-4.6/pexpect/bashrc.sh | 16 - .../module/pexpect-4.6/pexpect/exceptions.py | 35 - .../module/pexpect-4.6/pexpect/expect.py | 306 ------- .../module/pexpect-4.6/pexpect/fdpexpect.py | 148 ---- .../module/pexpect-4.6/pexpect/popen_spawn.py | 188 ---- .../module/pexpect-4.6/pexpect/pty_spawn.py | 833 ----------------- .../module/pexpect-4.6/pexpect/pxssh.py | 499 ----------- .../module/pexpect-4.6/pexpect/replwrap.py | 122 --- .../Python/module/pexpect-4.6/pexpect/run.py | 157 ---- .../module/pexpect-4.6/pexpect/screen.py | 431 --------- .../module/pexpect-4.6/pexpect/spawnbase.py | 522 ----------- .../module/pexpect-4.6/pexpect/utils.py | 187 ---- .../pexpect-4.6/requirements-testing.txt | 5 - .../Python/module/pexpect-4.6/setup.cfg | 5 - .../Python/module/pexpect-4.6/setup.py | 71 -- .../Python/module/ptyprocess-0.6.0/.gitignore | 7 - .../module/ptyprocess-0.6.0/.travis.yml | 9 - .../Python/module/ptyprocess-0.6.0/LICENSE | 16 - .../Python/module/ptyprocess-0.6.0/README.rst | 15 - .../ptyprocess-0.6.0/ptyprocess/__init__.py | 4 - .../ptyprocess-0.6.0/ptyprocess/_fork_pty.py | 78 -- .../ptyprocess-0.6.0/ptyprocess/ptyprocess.py | 836 ------------------ .../ptyprocess-0.6.0/ptyprocess/util.py | 71 -- .../module/ptyprocess-0.6.0/pyproject.toml | 24 - .../module/ptyprocess-0.6.0/readthedocs.yml | 2 - 35 files changed, 5579 deletions(-) delete mode 100644 lldb/third_party/Python/module/pexpect-4.6/.gitignore delete mode 100644 lldb/third_party/Python/module/pexpect-4.6/.travis.yml delete mode 100644 lldb/third_party/Python/module/pexpect-4.6/DEVELOPERS.rst delete mode 100644 lldb/third_party/Python/module/pexpect-4.6/LICENSE delete mode 100644 lldb/third_party/Python/module/pexpect-4.6/MANIFEST.in delete mode 100644 lldb/third_party/Python/module/pexpect-4.6/README.rst delete mode 100644 lldb/third_party/Python/module/pexpect-4.6/pexpect/ANSI.py delete mode 100644 lldb/third_party/Python/module/pexpect-4.6/pexpect/FSM.py delete mode 100644 lldb/third_party/Python/module/pexpect-4.6/pexpect/__init__.py delete mode 100644 lldb/third_party/Python/module/pexpect-4.6/pexpect/_async.py delete mode 100644 lldb/third_party/Python/module/pexpect-4.6/pexpect/bashrc.sh delete mode 100644 lldb/third_party/Python/module/pexpect-4.6/pexpect/exceptions.py delete mode 100644 lldb/third_party/Python/module/pexpect-4.6/pexpect/expect.py delete mode 100644 lldb/third_party/Python/module/pexpect-4.6/pexpect/fdpexpect.py delete mode 100644 lldb/third_party/Python/module/pexpect-4.6/pexpect/popen_spawn.py delete mode 100644 lldb/third_party/Python/module/pexpect-4.6/pexpect/pty_spawn.py delete mode 100644 lldb/third_party/Python/module/pexpect-4.6/pexpect/pxssh.py delete mode 100644 lldb/third_party/Python/module/pexpect-4.6/pexpect/replwrap.py delete mode 100644 lldb/third_party/Python/module/pexpect-4.6/pexpect/run.py delete mode 100644 lldb/third_party/Python/module/pexpect-4.6/pexpect/screen.py delete mode 100644 lldb/third_party/Python/module/pexpect-4.6/pexpect/spawnbase.py delete mode 100644 lldb/third_party/Python/module/pexpect-4.6/pexpect/utils.py delete mode 100644 lldb/third_party/Python/module/pexpect-4.6/requirements-testing.txt delete mode 100644 lldb/third_party/Python/module/pexpect-4.6/setup.cfg delete mode 100644 lldb/third_party/Python/module/pexpect-4.6/setup.py delete mode 100644 lldb/third_party/Python/module/ptyprocess-0.6.0/.gitignore delete mode 100644 lldb/third_party/Python/module/ptyprocess-0.6.0/.travis.yml delete mode 100644 lldb/third_party/Python/module/ptyprocess-0.6.0/LICENSE delete mode 100644 lldb/third_party/Python/module/ptyprocess-0.6.0/README.rst delete mode 100644 lldb/third_party/Python/module/ptyprocess-0.6.0/ptyprocess/__init__.py delete mode 100644 lldb/third_party/Python/module/ptyprocess-0.6.0/ptyprocess/_fork_pty.py delete mode 100644 lldb/third_party/Python/module/ptyprocess-0.6.0/ptyprocess/ptyprocess.py delete mode 100644 lldb/third_party/Python/module/ptyprocess-0.6.0/ptyprocess/util.py delete mode 100644 lldb/third_party/Python/module/ptyprocess-0.6.0/pyproject.toml delete mode 100644 lldb/third_party/Python/module/ptyprocess-0.6.0/readthedocs.yml diff --git a/lldb/third_party/Python/module/pexpect-4.6/.gitignore b/lldb/third_party/Python/module/pexpect-4.6/.gitignore deleted file mode 100644 index 22cd4785f715..000000000000 --- a/lldb/third_party/Python/module/pexpect-4.6/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -*.pyc -doc/_build -tests/log -build/ -dist/ -MANIFEST -*~ -.coverage* -htmlcov -*.egg-info/ -.cache/ diff --git a/lldb/third_party/Python/module/pexpect-4.6/.travis.yml b/lldb/third_party/Python/module/pexpect-4.6/.travis.yml deleted file mode 100644 index 40d962295012..000000000000 --- a/lldb/third_party/Python/module/pexpect-4.6/.travis.yml +++ /dev/null @@ -1,31 +0,0 @@ -language: python - -python: - - 2.7 - - 3.3 - - 3.4 - - 3.5 - - 3.6 - - pypy - - nightly - -matrix: - allow_failures: - # PyPy on Travis is currently incompatible with Cryptography. - - python: pypy - -install: - - export PYTHONIOENCODING=UTF8 - - pip install coveralls pytest-cov ptyprocess - -script: - - ./tools/display-sighandlers.py - - ./tools/display-terminalinfo.py - - py.test --cov pexpect --cov-config .coveragerc - -after_success: - - coverage combine - - coveralls - -# Use new Travis stack, should be faster -sudo: false diff --git a/lldb/third_party/Python/module/pexpect-4.6/DEVELOPERS.rst b/lldb/third_party/Python/module/pexpect-4.6/DEVELOPERS.rst deleted file mode 100644 index bf2bb9f30f8a..000000000000 --- a/lldb/third_party/Python/module/pexpect-4.6/DEVELOPERS.rst +++ /dev/null @@ -1,12 +0,0 @@ -To run the tests, use `py.test `_:: - - py.test tests - -The tests are all located in the tests/ directory. To add a new unit -test all you have to do is create the file in the tests/ directory with a -filename in this format:: - - test_*.py - -New test case classes may wish to inherit from ``PexpectTestCase.PexpectTestCase`` -in the tests directory, which sets up some convenient functionality. diff --git a/lldb/third_party/Python/module/pexpect-4.6/LICENSE b/lldb/third_party/Python/module/pexpect-4.6/LICENSE deleted file mode 100644 index 754db5afcb82..000000000000 --- a/lldb/third_party/Python/module/pexpect-4.6/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -ISC LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2013-2014, Pexpect development team - Copyright (c) 2012, Noah Spurrier - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - diff --git a/lldb/third_party/Python/module/pexpect-4.6/MANIFEST.in b/lldb/third_party/Python/module/pexpect-4.6/MANIFEST.in deleted file mode 100644 index 32c72ba17124..000000000000 --- a/lldb/third_party/Python/module/pexpect-4.6/MANIFEST.in +++ /dev/null @@ -1,6 +0,0 @@ -recursive-include doc * -prune doc/_build -recursive-include examples * -include .coveragerc README.rst LICENSE pexpect/bashrc.sh -recursive-include tests * -global-exclude __pycache__ *.pyc *~ diff --git a/lldb/third_party/Python/module/pexpect-4.6/README.rst b/lldb/third_party/Python/module/pexpect-4.6/README.rst deleted file mode 100644 index 0f5cb98ceb98..000000000000 --- a/lldb/third_party/Python/module/pexpect-4.6/README.rst +++ /dev/null @@ -1,55 +0,0 @@ -.. image:: https://travis-ci.org/pexpect/pexpect.svg?branch=master - :target: https://travis-ci.org/pexpect/pexpect - :align: right - :alt: Build status - -Pexpect is a Pure Python Expect-like module - -Pexpect makes Python a better tool for controlling other applications. - -Pexpect is a pure Python module for spawning child applications; controlling -them; and responding to expected patterns in their output. Pexpect works like -Don Libes' Expect. Pexpect allows your script to spawn a child application and -control it as if a human were typing commands. - -Pexpect can be used for automating interactive applications such as ssh, ftp, -passwd, telnet, etc. It can be used to a automate setup scripts for duplicating -software package installations on different servers. It can be used for -automated software testing. Pexpect is in the spirit of Don Libes' Expect, but -Pexpect is pure Python. - -The main features of Pexpect require the pty module in the Python standard -library, which is only available on Unix-like systems. Some features—waiting -for patterns from file descriptors or subprocesses—are also available on -Windows. - -If you want to work with the development version of the source code then please -read the DEVELOPERS.rst document in the root of the source code tree. - -Free, open source, and all that good stuff. - -You can install Pexpect using pip:: - - pip install pexpect - -`Docs on ReadTheDocs `_ - -PEXPECT LICENSE:: - - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2013-2016, Pexpect development team - Copyright (c) 2012, Noah Spurrier - - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -This license is approved by the OSI and FSF as GPL-compatible. diff --git a/lldb/third_party/Python/module/pexpect-4.6/pexpect/ANSI.py b/lldb/third_party/Python/module/pexpect-4.6/pexpect/ANSI.py deleted file mode 100644 index 1cd2e90e7ab0..000000000000 --- a/lldb/third_party/Python/module/pexpect-4.6/pexpect/ANSI.py +++ /dev/null @@ -1,351 +0,0 @@ -'''This implements an ANSI (VT100) terminal emulator as a subclass of screen. - -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' - -# references: -# http://en.wikipedia.org/wiki/ANSI_escape_code -# http://www.retards.org/terminals/vt102.html -# http://vt100.net/docs/vt102-ug/contents.html -# http://vt100.net/docs/vt220-rm/ -# http://www.termsys.demon.co.uk/vtansi.htm - -from . import screen -from . import FSM -import string - -# -# The 'Do.*' functions are helper functions for the ANSI class. -# -def DoEmit (fsm): - - screen = fsm.memory[0] - screen.write_ch(fsm.input_symbol) - -def DoStartNumber (fsm): - - fsm.memory.append (fsm.input_symbol) - -def DoBuildNumber (fsm): - - ns = fsm.memory.pop() - ns = ns + fsm.input_symbol - fsm.memory.append (ns) - -def DoBackOne (fsm): - - screen = fsm.memory[0] - screen.cursor_back () - -def DoBack (fsm): - - count = int(fsm.memory.pop()) - screen = fsm.memory[0] - screen.cursor_back (count) - -def DoDownOne (fsm): - - screen = fsm.memory[0] - screen.cursor_down () - -def DoDown (fsm): - - count = int(fsm.memory.pop()) - screen = fsm.memory[0] - screen.cursor_down (count) - -def DoForwardOne (fsm): - - screen = fsm.memory[0] - screen.cursor_forward () - -def DoForward (fsm): - - count = int(fsm.memory.pop()) - screen = fsm.memory[0] - screen.cursor_forward (count) - -def DoUpReverse (fsm): - - screen = fsm.memory[0] - screen.cursor_up_reverse() - -def DoUpOne (fsm): - - screen = fsm.memory[0] - screen.cursor_up () - -def DoUp (fsm): - - count = int(fsm.memory.pop()) - screen = fsm.memory[0] - screen.cursor_up (count) - -def DoHome (fsm): - - c = int(fsm.memory.pop()) - r = int(fsm.memory.pop()) - screen = fsm.memory[0] - screen.cursor_home (r,c) - -def DoHomeOrigin (fsm): - - c = 1 - r = 1 - screen = fsm.memory[0] - screen.cursor_home (r,c) - -def DoEraseDown (fsm): - - screen = fsm.memory[0] - screen.erase_down() - -def DoErase (fsm): - - arg = int(fsm.memory.pop()) - screen = fsm.memory[0] - if arg == 0: - screen.erase_down() - elif arg == 1: - screen.erase_up() - elif arg == 2: - screen.erase_screen() - -def DoEraseEndOfLine (fsm): - - screen = fsm.memory[0] - screen.erase_end_of_line() - -def DoEraseLine (fsm): - - arg = int(fsm.memory.pop()) - screen = fsm.memory[0] - if arg == 0: - screen.erase_end_of_line() - elif arg == 1: - screen.erase_start_of_line() - elif arg == 2: - screen.erase_line() - -def DoEnableScroll (fsm): - - screen = fsm.memory[0] - screen.scroll_screen() - -def DoCursorSave (fsm): - - screen = fsm.memory[0] - screen.cursor_save_attrs() - -def DoCursorRestore (fsm): - - screen = fsm.memory[0] - screen.cursor_restore_attrs() - -def DoScrollRegion (fsm): - - screen = fsm.memory[0] - r2 = int(fsm.memory.pop()) - r1 = int(fsm.memory.pop()) - screen.scroll_screen_rows (r1,r2) - -def DoMode (fsm): - - screen = fsm.memory[0] - mode = fsm.memory.pop() # Should be 4 - # screen.setReplaceMode () - -def DoLog (fsm): - - screen = fsm.memory[0] - fsm.memory = [screen] - fout = open ('log', 'a') - fout.write (fsm.input_symbol + ',' + fsm.current_state + '\n') - fout.close() - -class term (screen.screen): - - '''This class is an abstract, generic terminal. - This does nothing. This is a placeholder that - provides a common base class for other terminals - such as an ANSI terminal. ''' - - def __init__ (self, r=24, c=80, *args, **kwargs): - - screen.screen.__init__(self, r,c,*args,**kwargs) - -class ANSI (term): - '''This class implements an ANSI (VT100) terminal. - It is a stream filter that recognizes ANSI terminal - escape sequences and maintains the state of a screen object. ''' - - def __init__ (self, r=24,c=80,*args,**kwargs): - - term.__init__(self,r,c,*args,**kwargs) - - #self.screen = screen (24,80) - self.state = FSM.FSM ('INIT',[self]) - self.state.set_default_transition (DoLog, 'INIT') - self.state.add_transition_any ('INIT', DoEmit, 'INIT') - self.state.add_transition ('\x1b', 'INIT', None, 'ESC') - self.state.add_transition_any ('ESC', DoLog, 'INIT') - self.state.add_transition ('(', 'ESC', None, 'G0SCS') - self.state.add_transition (')', 'ESC', None, 'G1SCS') - self.state.add_transition_list ('AB012', 'G0SCS', None, 'INIT') - self.state.add_transition_list ('AB012', 'G1SCS', None, 'INIT') - self.state.add_transition ('7', 'ESC', DoCursorSave, 'INIT') - self.state.add_transition ('8', 'ESC', DoCursorRestore, 'INIT') - self.state.add_transition ('M', 'ESC', DoUpReverse, 'INIT') - self.state.add_transition ('>', 'ESC', DoUpReverse, 'INIT') - self.state.add_transition ('<', 'ESC', DoUpReverse, 'INIT') - self.state.add_transition ('=', 'ESC', None, 'INIT') # Selects application keypad. - self.state.add_transition ('#', 'ESC', None, 'GRAPHICS_POUND') - self.state.add_transition_any ('GRAPHICS_POUND', None, 'INIT') - self.state.add_transition ('[', 'ESC', None, 'ELB') - # ELB means Escape Left Bracket. That is ^[[ - self.state.add_transition ('H', 'ELB', DoHomeOrigin, 'INIT') - self.state.add_transition ('D', 'ELB', DoBackOne, 'INIT') - self.state.add_transition ('B', 'ELB', DoDownOne, 'INIT') - self.state.add_transition ('C', 'ELB', DoForwardOne, 'INIT') - self.state.add_transition ('A', 'ELB', DoUpOne, 'INIT') - self.state.add_transition ('J', 'ELB', DoEraseDown, 'INIT') - self.state.add_transition ('K', 'ELB', DoEraseEndOfLine, 'INIT') - self.state.add_transition ('r', 'ELB', DoEnableScroll, 'INIT') - self.state.add_transition ('m', 'ELB', self.do_sgr, 'INIT') - self.state.add_transition ('?', 'ELB', None, 'MODECRAP') - self.state.add_transition_list (string.digits, 'ELB', DoStartNumber, 'NUMBER_1') - self.state.add_transition_list (string.digits, 'NUMBER_1', DoBuildNumber, 'NUMBER_1') - self.state.add_transition ('D', 'NUMBER_1', DoBack, 'INIT') - self.state.add_transition ('B', 'NUMBER_1', DoDown, 'INIT') - self.state.add_transition ('C', 'NUMBER_1', DoForward, 'INIT') - self.state.add_transition ('A', 'NUMBER_1', DoUp, 'INIT') - self.state.add_transition ('J', 'NUMBER_1', DoErase, 'INIT') - self.state.add_transition ('K', 'NUMBER_1', DoEraseLine, 'INIT') - self.state.add_transition ('l', 'NUMBER_1', DoMode, 'INIT') - ### It gets worse... the 'm' code can have infinite number of - ### number;number;number before it. I've never seen more than two, - ### but the specs say it's allowed. crap! - self.state.add_transition ('m', 'NUMBER_1', self.do_sgr, 'INIT') - ### LED control. Same implementation problem as 'm' code. - self.state.add_transition ('q', 'NUMBER_1', self.do_decsca, 'INIT') - - # \E[?47h switch to alternate screen - # \E[?47l restores to normal screen from alternate screen. - self.state.add_transition_list (string.digits, 'MODECRAP', DoStartNumber, 'MODECRAP_NUM') - self.state.add_transition_list (string.digits, 'MODECRAP_NUM', DoBuildNumber, 'MODECRAP_NUM') - self.state.add_transition ('l', 'MODECRAP_NUM', self.do_modecrap, 'INIT') - self.state.add_transition ('h', 'MODECRAP_NUM', self.do_modecrap, 'INIT') - -#RM Reset Mode Esc [ Ps l none - self.state.add_transition (';', 'NUMBER_1', None, 'SEMICOLON') - self.state.add_transition_any ('SEMICOLON', DoLog, 'INIT') - self.state.add_transition_list (string.digits, 'SEMICOLON', DoStartNumber, 'NUMBER_2') - self.state.add_transition_list (string.digits, 'NUMBER_2', DoBuildNumber, 'NUMBER_2') - self.state.add_transition_any ('NUMBER_2', DoLog, 'INIT') - self.state.add_transition ('H', 'NUMBER_2', DoHome, 'INIT') - self.state.add_transition ('f', 'NUMBER_2', DoHome, 'INIT') - self.state.add_transition ('r', 'NUMBER_2', DoScrollRegion, 'INIT') - ### It gets worse... the 'm' code can have infinite number of - ### number;number;number before it. I've never seen more than two, - ### but the specs say it's allowed. crap! - self.state.add_transition ('m', 'NUMBER_2', self.do_sgr, 'INIT') - ### LED control. Same problem as 'm' code. - self.state.add_transition ('q', 'NUMBER_2', self.do_decsca, 'INIT') - self.state.add_transition (';', 'NUMBER_2', None, 'SEMICOLON_X') - - # Create a state for 'q' and 'm' which allows an infinite number of ignored numbers - self.state.add_transition_any ('SEMICOLON_X', DoLog, 'INIT') - self.state.add_transition_list (string.digits, 'SEMICOLON_X', DoStartNumber, 'NUMBER_X') - self.state.add_transition_list (string.digits, 'NUMBER_X', DoBuildNumber, 'NUMBER_X') - self.state.add_transition_any ('NUMBER_X', DoLog, 'INIT') - self.state.add_transition ('m', 'NUMBER_X', self.do_sgr, 'INIT') - self.state.add_transition ('q', 'NUMBER_X', self.do_decsca, 'INIT') - self.state.add_transition (';', 'NUMBER_X', None, 'SEMICOLON_X') - - def process (self, c): - """Process a single character. Called by :meth:`write`.""" - if isinstance(c, bytes): - c = self._decode(c) - self.state.process(c) - - def process_list (self, l): - - self.write(l) - - def write (self, s): - """Process text, writing it to the virtual screen while handling - ANSI escape codes. - """ - if isinstance(s, bytes): - s = self._decode(s) - for c in s: - self.process(c) - - def flush (self): - pass - - def write_ch (self, ch): - '''This puts a character at the current cursor position. The cursor - position is moved forward with wrap-around, but no scrolling is done if - the cursor hits the lower-right corner of the screen. ''' - - if isinstance(ch, bytes): - ch = self._decode(ch) - - #\r and \n both produce a call to cr() and lf(), respectively. - ch = ch[0] - - if ch == u'\r': - self.cr() - return - if ch == u'\n': - self.crlf() - return - if ch == chr(screen.BS): - self.cursor_back() - return - self.put_abs(self.cur_r, self.cur_c, ch) - old_r = self.cur_r - old_c = self.cur_c - self.cursor_forward() - if old_c == self.cur_c: - self.cursor_down() - if old_r != self.cur_r: - self.cursor_home (self.cur_r, 1) - else: - self.scroll_up () - self.cursor_home (self.cur_r, 1) - self.erase_line() - - def do_sgr (self, fsm): - '''Select Graphic Rendition, e.g. color. ''' - screen = fsm.memory[0] - fsm.memory = [screen] - - def do_decsca (self, fsm): - '''Select character protection attribute. ''' - screen = fsm.memory[0] - fsm.memory = [screen] - - def do_modecrap (self, fsm): - '''Handler for \x1b[?h and \x1b[?l. If anyone - wanted to actually use these, they'd need to add more states to the - FSM rather than just improve or override this method. ''' - screen = fsm.memory[0] - fsm.memory = [screen] diff --git a/lldb/third_party/Python/module/pexpect-4.6/pexpect/FSM.py b/lldb/third_party/Python/module/pexpect-4.6/pexpect/FSM.py deleted file mode 100644 index 46b392ea08aa..000000000000 --- a/lldb/third_party/Python/module/pexpect-4.6/pexpect/FSM.py +++ /dev/null @@ -1,334 +0,0 @@ -#!/usr/bin/env python - -'''This module implements a Finite State Machine (FSM). In addition to state -this FSM also maintains a user defined "memory". So this FSM can be used as a -Push-down Automata (PDA) since a PDA is a FSM + memory. - -The following describes how the FSM works, but you will probably also need to -see the example function to understand how the FSM is used in practice. - -You define an FSM by building tables of transitions. For a given input symbol -the process() method uses these tables to decide what action to call and what -the next state will be. The FSM has a table of transitions that associate: - - (input_symbol, current_state) --> (action, next_state) - -Where "action" is a function you define. The symbols and states can be any -objects. You use the add_transition() and add_transition_list() methods to add -to the transition table. The FSM also has a table of transitions that -associate: - - (current_state) --> (action, next_state) - -You use the add_transition_any() method to add to this transition table. The -FSM also has one default transition that is not associated with any specific -input_symbol or state. You use the set_default_transition() method to set the -default transition. - -When an action function is called it is passed a reference to the FSM. The -action function may then access attributes of the FSM such as input_symbol, -current_state, or "memory". The "memory" attribute can be any object that you -want to pass along to the action functions. It is not used by the FSM itself. -For parsing you would typically pass a list to be used as a stack. - -The processing sequence is as follows. The process() method is given an -input_symbol to process. The FSM will search the table of transitions that -associate: - - (input_symbol, current_state) --> (action, next_state) - -If the pair (input_symbol, current_state) is found then process() will call the -associated action function and then set the current state to the next_state. - -If the FSM cannot find a match for (input_symbol, current_state) it will then -search the table of transitions that associate: - - (current_state) --> (action, next_state) - -If the current_state is found then the process() method will call the -associated action function and then set the current state to the next_state. -Notice that this table lacks an input_symbol. It lets you define transitions -for a current_state and ANY input_symbol. Hence, it is called the "any" table. -Remember, it is always checked after first searching the table for a specific -(input_symbol, current_state). - -For the case where the FSM did not match either of the previous two cases the -FSM will try to use the default transition. If the default transition is -defined then the process() method will call the associated action function and -then set the current state to the next_state. This lets you define a default -transition as a catch-all case. You can think of it as an exception handler. -There can be only one default transition. - -Finally, if none of the previous cases are defined for an input_symbol and -current_state then the FSM will raise an exception. This may be desirable, but -you can always prevent this just by defining a default transition. - -Noah Spurrier 20020822 - -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' - -class ExceptionFSM(Exception): - - '''This is the FSM Exception class.''' - - def __init__(self, value): - self.value = value - - def __str__(self): - return 'ExceptionFSM: ' + str(self.value) - -class FSM: - - '''This is a Finite State Machine (FSM). - ''' - - def __init__(self, initial_state, memory=None): - - '''This creates the FSM. You set the initial state here. The "memory" - attribute is any object that you want to pass along to the action - functions. It is not used by the FSM. For parsing you would typically - pass a list to be used as a stack. ''' - - # Map (input_symbol, current_state) --> (action, next_state). - self.state_transitions = {} - # Map (current_state) --> (action, next_state). - self.state_transitions_any = {} - self.default_transition = None - - self.input_symbol = None - self.initial_state = initial_state - self.current_state = self.initial_state - self.next_state = None - self.action = None - self.memory = memory - - def reset (self): - - '''This sets the current_state to the initial_state and sets - input_symbol to None. The initial state was set by the constructor - __init__(). ''' - - self.current_state = self.initial_state - self.input_symbol = None - - def add_transition (self, input_symbol, state, action=None, next_state=None): - - '''This adds a transition that associates: - - (input_symbol, current_state) --> (action, next_state) - - The action may be set to None in which case the process() method will - ignore the action and only set the next_state. The next_state may be - set to None in which case the current state will be unchanged. - - You can also set transitions for a list of symbols by using - add_transition_list(). ''' - - if next_state is None: - next_state = state - self.state_transitions[(input_symbol, state)] = (action, next_state) - - def add_transition_list (self, list_input_symbols, state, action=None, next_state=None): - - '''This adds the same transition for a list of input symbols. - You can pass a list or a string. Note that it is handy to use - string.digits, string.whitespace, string.letters, etc. to add - transitions that match character classes. - - The action may be set to None in which case the process() method will - ignore the action and only set the next_state. The next_state may be - set to None in which case the current state will be unchanged. ''' - - if next_state is None: - next_state = state - for input_symbol in list_input_symbols: - self.add_transition (input_symbol, state, action, next_state) - - def add_transition_any (self, state, action=None, next_state=None): - - '''This adds a transition that associates: - - (current_state) --> (action, next_state) - - That is, any input symbol will match the current state. - The process() method checks the "any" state associations after it first - checks for an exact match of (input_symbol, current_state). - - The action may be set to None in which case the process() method will - ignore the action and only set the next_state. The next_state may be - set to None in which case the current state will be unchanged. ''' - - if next_state is None: - next_state = state - self.state_transitions_any [state] = (action, next_state) - - def set_default_transition (self, action, next_state): - - '''This sets the default transition. This defines an action and - next_state if the FSM cannot find the input symbol and the current - state in the transition list and if the FSM cannot find the - current_state in the transition_any list. This is useful as a final - fall-through state for catching errors and undefined states. - - The default transition can be removed by setting the attribute - default_transition to None. ''' - - self.default_transition = (action, next_state) - - def get_transition (self, input_symbol, state): - - '''This returns (action, next state) given an input_symbol and state. - This does not modify the FSM state, so calling this method has no side - effects. Normally you do not call this method directly. It is called by - process(). - - The sequence of steps to check for a defined transition goes from the - most specific to the least specific. - - 1. Check state_transitions[] that match exactly the tuple, - (input_symbol, state) - - 2. Check state_transitions_any[] that match (state) - In other words, match a specific state and ANY input_symbol. - - 3. Check if the default_transition is defined. - This catches any input_symbol and any state. - This is a handler for errors, undefined states, or defaults. - - 4. No transition was defined. If we get here then raise an exception. - ''' - - if (input_symbol, state) in self.state_transitions: - return self.state_transitions[(input_symbol, state)] - elif state in self.state_transitions_any: - return self.state_transitions_any[state] - elif self.default_transition is not None: - return self.default_transition - else: - raise ExceptionFSM ('Transition is undefined: (%s, %s).' % - (str(input_symbol), str(state)) ) - - def process (self, input_symbol): - - '''This is the main method that you call to process input. This may - cause the FSM to change state and call an action. This method calls - get_transition() to find the action and next_state associated with the - input_symbol and current_state. If the action is None then the action - is not called and only the current state is changed. This method - processes one complete input symbol. You can process a list of symbols - (or a string) by calling process_list(). ''' - - self.input_symbol = input_symbol - (self.action, self.next_state) = self.get_transition (self.input_symbol, self.current_state) - if self.action is not None: - self.action (self) - self.current_state = self.next_state - self.next_state = None - - def process_list (self, input_symbols): - - '''This takes a list and sends each element to process(). The list may - be a string or any iterable object. ''' - - for s in input_symbols: - self.process (s) - -############################################################################## -# The following is an example that demonstrates the use of the FSM class to -# process an RPN expression. Run this module from the command line. You will -# get a prompt > for input. Enter an RPN Expression. Numbers may be integers. -# Operators are * / + - Use the = sign to evaluate and print the expression. -# For example: -# -# 167 3 2 2 * * * 1 - = -# -# will print: -# -# 2003 -############################################################################## - -import sys -import string - -PY3 = (sys.version_info[0] >= 3) - -# -# These define the actions. -# Note that "memory" is a list being used as a stack. -# - -def BeginBuildNumber (fsm): - fsm.memory.append (fsm.input_symbol) - -def BuildNumber (fsm): - s = fsm.memory.pop () - s = s + fsm.input_symbol - fsm.memory.append (s) - -def EndBuildNumber (fsm): - s = fsm.memory.pop () - fsm.memory.append (int(s)) - -def DoOperator (fsm): - ar = fsm.memory.pop() - al = fsm.memory.pop() - if fsm.input_symbol == '+': - fsm.memory.append (al + ar) - elif fsm.input_symbol == '-': - fsm.memory.append (al - ar) - elif fsm.input_symbol == '*': - fsm.memory.append (al * ar) - elif fsm.input_symbol == '/': - fsm.memory.append (al / ar) - -def DoEqual (fsm): - print(str(fsm.memory.pop())) - -def Error (fsm): - print('That does not compute.') - print(str(fsm.input_symbol)) - -def main(): - - '''This is where the example starts and the FSM state transitions are - defined. Note that states are strings (such as 'INIT'). This is not - necessary, but it makes the example easier to read. ''' - - f = FSM ('INIT', []) - f.set_default_transition (Error, 'INIT') - f.add_transition_any ('INIT', None, 'INIT') - f.add_transition ('=', 'INIT', DoEqual, 'INIT') - f.add_transition_list (string.digits, 'INIT', BeginBuildNumber, 'BUILDING_NUMBER') - f.add_transition_list (string.digits, 'BUILDING_NUMBER', BuildNumber, 'BUILDING_NUMBER') - f.add_transition_list (string.whitespace, 'BUILDING_NUMBER', EndBuildNumber, 'INIT') - f.add_transition_list ('+-*/', 'INIT', DoOperator, 'INIT') - - print() - print('Enter an RPN Expression.') - print('Numbers may be integers. Operators are * / + -') - print('Use the = sign to evaluate and print the expression.') - print('For example: ') - print(' 167 3 2 2 * * * 1 - =') - inputstr = (input if PY3 else raw_input)('> ') # analysis:ignore - f.process_list(inputstr) - - -if __name__ == '__main__': - main() diff --git a/lldb/third_party/Python/module/pexpect-4.6/pexpect/__init__.py b/lldb/third_party/Python/module/pexpect-4.6/pexpect/__init__.py deleted file mode 100644 index 2a18d1911a9c..000000000000 --- a/lldb/third_party/Python/module/pexpect-4.6/pexpect/__init__.py +++ /dev/null @@ -1,85 +0,0 @@ -'''Pexpect is a Python module for spawning child applications and controlling -them automatically. Pexpect can be used for automating interactive applications -such as ssh, ftp, passwd, telnet, etc. It can be used to a automate setup -scripts for duplicating software package installations on different servers. It -can be used for automated software testing. Pexpect is in the spirit of Don -Libes' Expect, but Pexpect is pure Python. Other Expect-like modules for Python -require TCL and Expect or require C extensions to be compiled. Pexpect does not -use C, Expect, or TCL extensions. It should work on any platform that supports -the standard Python pty module. The Pexpect interface focuses on ease of use so -that simple tasks are easy. - -There are two main interfaces to the Pexpect system; these are the function, -run() and the class, spawn. The spawn class is more powerful. The run() -function is simpler than spawn, and is good for quickly calling program. When -you call the run() function it executes a given program and then returns the -output. This is a handy replacement for os.system(). - -For example:: - - pexpect.run('ls -la') - -The spawn class is the more powerful interface to the Pexpect system. You can -use this to spawn a child program then interact with it by sending input and -expecting responses (waiting for patterns in the child's output). - -For example:: - - child = pexpect.spawn('scp foo user@example.com:.') - child.expect('Password:') - child.sendline(mypassword) - -This works even for commands that ask for passwords or other input outside of -the normal stdio streams. For example, ssh reads input directly from the TTY -device which bypasses stdin. - -Credits: Noah Spurrier, Richard Holden, Marco Molteni, Kimberley Burchett, -Robert Stone, Hartmut Goebel, Chad Schroeder, Erick Tryzelaar, Dave Kirby, Ids -vander Molen, George Todd, Noel Taylor, Nicolas D. Cesar, Alexander Gattin, -Jacques-Etienne Baudoux, Geoffrey Marshall, Francisco Lourenco, Glen Mabey, -Karthik Gurusamy, Fernando Perez, Corey Minyard, Jon Cohen, Guillaume -Chazarain, Andrew Ryan, Nick Craig-Wood, Andrew Stone, Jorgen Grahn, John -Spiegel, Jan Grant, and Shane Kerr. Let me know if I forgot anyone. - -Pexpect is free, open source, and all that good stuff. -http://pexpect.sourceforge.net/ - -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' - -import sys -PY3 = (sys.version_info[0] >= 3) - -from .exceptions import ExceptionPexpect, EOF, TIMEOUT -from .utils import split_command_line, which, is_executable_file -from .expect import Expecter, searcher_re, searcher_string - -if sys.platform != 'win32': - # On Unix, these are available at the top level for backwards compatibility - from .pty_spawn import spawn, spawnu - from .run import run, runu - -__version__ = '4.6.0' -__revision__ = '' -__all__ = ['ExceptionPexpect', 'EOF', 'TIMEOUT', 'spawn', 'spawnu', 'run', 'runu', - 'which', 'split_command_line', '__version__', '__revision__'] - - - -# vim: set shiftround expandtab tabstop=4 shiftwidth=4 ft=python autoindent : diff --git a/lldb/third_party/Python/module/pexpect-4.6/pexpect/_async.py b/lldb/third_party/Python/module/pexpect-4.6/pexpect/_async.py deleted file mode 100644 index bdd515b1f509..000000000000 --- a/lldb/third_party/Python/module/pexpect-4.6/pexpect/_async.py +++ /dev/null @@ -1,87 +0,0 @@ -import asyncio -import errno - -from pexpect import EOF - -@asyncio.coroutine -def expect_async(expecter, timeout=None): - # First process data that was previously read - if it maches, we don't need - # async stuff. - previously_read = expecter.spawn.buffer - expecter.spawn._buffer = expecter.spawn.buffer_type() - expecter.spawn._before = expecter.spawn.buffer_type() - idx = expecter.new_data(previously_read) - if idx is not None: - return idx - if not expecter.spawn.async_pw_transport: - pw = PatternWaiter() - pw.set_expecter(expecter) - transport, pw = yield from asyncio.get_event_loop()\ - .connect_read_pipe(lambda: pw, expecter.spawn) - expecter.spawn.async_pw_transport = pw, transport - else: - pw, transport = expecter.spawn.async_pw_transport - pw.set_expecter(expecter) - transport.resume_reading() - try: - return (yield from asyncio.wait_for(pw.fut, timeout)) - except asyncio.TimeoutError as e: - transport.pause_reading() - return expecter.timeout(e) - - -class PatternWaiter(asyncio.Protocol): - transport = None - - def set_expecter(self, expecter): - self.expecter = expecter - self.fut = asyncio.Future() - - def found(self, result): - if not self.fut.done(): - self.fut.set_result(result) - self.transport.pause_reading() - - def error(self, exc): - if not self.fut.done(): - self.fut.set_exception(exc) - self.transport.pause_reading() - - def connection_made(self, transport): - self.transport = transport - - def data_received(self, data): - spawn = self.expecter.spawn - s = spawn._decoder.decode(data) - spawn._log(s, 'read') - - if self.fut.done(): - spawn._buffer.write(s) - return - - try: - index = self.expecter.new_data(s) - if index is not None: - # Found a match - self.found(index) - except Exception as e: - self.expecter.errored() - self.error(e) - - def eof_received(self): - # N.B. If this gets called, async will close the pipe (the spawn object) - # for us - try: - self.expecter.spawn.flag_eof = True - index = self.expecter.eof() - except EOF as e: - self.error(e) - else: - self.found(index) - - def connection_lost(self, exc): - if isinstance(exc, OSError) and exc.errno == errno.EIO: - # We may get here without eof_received being called, e.g on Linux - self.eof_received() - elif exc is not None: - self.error(exc) diff --git a/lldb/third_party/Python/module/pexpect-4.6/pexpect/bashrc.sh b/lldb/third_party/Python/module/pexpect-4.6/pexpect/bashrc.sh deleted file mode 100644 index c734ac90b852..000000000000 --- a/lldb/third_party/Python/module/pexpect-4.6/pexpect/bashrc.sh +++ /dev/null @@ -1,16 +0,0 @@ -# Different platforms have different names for the systemwide bashrc -if [[ -f /etc/bashrc ]]; then - source /etc/bashrc -fi -if [[ -f /etc/bash.bashrc ]]; then - source /etc/bash.bashrc -fi -if [[ -f ~/.bashrc ]]; then - source ~/.bashrc -fi - -# Reset PS1 so pexpect can find it -PS1="$" - -# Unset PROMPT_COMMAND, so that it can't change PS1 to something unexpected. -unset PROMPT_COMMAND diff --git a/lldb/third_party/Python/module/pexpect-4.6/pexpect/exceptions.py b/lldb/third_party/Python/module/pexpect-4.6/pexpect/exceptions.py deleted file mode 100644 index cb360f026143..000000000000 --- a/lldb/third_party/Python/module/pexpect-4.6/pexpect/exceptions.py +++ /dev/null @@ -1,35 +0,0 @@ -"""Exception classes used by Pexpect""" - -import traceback -import sys - -class ExceptionPexpect(Exception): - '''Base class for all exceptions raised by this module. - ''' - - def __init__(self, value): - super(ExceptionPexpect, self).__init__(value) - self.value = value - - def __str__(self): - return str(self.value) - - def get_trace(self): - '''This returns an abbreviated stack trace with lines that only concern - the caller. In other words, the stack trace inside the Pexpect module - is not included. ''' - - tblist = traceback.extract_tb(sys.exc_info()[2]) - tblist = [item for item in tblist if ('pexpect/__init__' not in item[0]) - and ('pexpect/expect' not in item[0])] - tblist = traceback.format_list(tblist) - return ''.join(tblist) - - -class EOF(ExceptionPexpect): - '''Raised when EOF is read from a child. - This usually means the child has exited.''' - - -class TIMEOUT(ExceptionPexpect): - '''Raised when a read time exceeds the timeout. ''' diff --git a/lldb/third_party/Python/module/pexpect-4.6/pexpect/expect.py b/lldb/third_party/Python/module/pexpect-4.6/pexpect/expect.py deleted file mode 100644 index 1c0275b4853a..000000000000 --- a/lldb/third_party/Python/module/pexpect-4.6/pexpect/expect.py +++ /dev/null @@ -1,306 +0,0 @@ -import time - -from .exceptions import EOF, TIMEOUT - -class Expecter(object): - def __init__(self, spawn, searcher, searchwindowsize=-1): - self.spawn = spawn - self.searcher = searcher - if searchwindowsize == -1: - searchwindowsize = spawn.searchwindowsize - self.searchwindowsize = searchwindowsize - - def new_data(self, data): - spawn = self.spawn - searcher = self.searcher - - pos = spawn._buffer.tell() - spawn._buffer.write(data) - spawn._before.write(data) - - # determine which chunk of data to search; if a windowsize is - # specified, this is the *new* data + the preceding bytes - if self.searchwindowsize: - spawn._buffer.seek(max(0, pos - self.searchwindowsize)) - window = spawn._buffer.read(self.searchwindowsize + len(data)) - else: - # otherwise, search the whole buffer (really slow for large datasets) - window = spawn.buffer - index = searcher.search(window, len(data)) - if index >= 0: - spawn._buffer = spawn.buffer_type() - spawn._buffer.write(window[searcher.end:]) - spawn.before = spawn._before.getvalue()[0:-(len(window) - searcher.start)] - spawn._before = spawn.buffer_type() - spawn.after = window[searcher.start: searcher.end] - spawn.match = searcher.match - spawn.match_index = index - # Found a match - return index - elif self.searchwindowsize: - spawn._buffer = spawn.buffer_type() - spawn._buffer.write(window) - - def eof(self, err=None): - spawn = self.spawn - - spawn.before = spawn.buffer - spawn._buffer = spawn.buffer_type() - spawn._before = spawn.buffer_type() - spawn.after = EOF - index = self.searcher.eof_index - if index >= 0: - spawn.match = EOF - spawn.match_index = index - return index - else: - spawn.match = None - spawn.match_index = None - msg = str(spawn) - msg += '\nsearcher: %s' % self.searcher - if err is not None: - msg = str(err) + '\n' + msg - raise EOF(msg) - - def timeout(self, err=None): - spawn = self.spawn - - spawn.before = spawn.buffer - spawn.after = TIMEOUT - index = self.searcher.timeout_index - if index >= 0: - spawn.match = TIMEOUT - spawn.match_index = index - return index - else: - spawn.match = None - spawn.match_index = None - msg = str(spawn) - msg += '\nsearcher: %s' % self.searcher - if err is not None: - msg = str(err) + '\n' + msg - raise TIMEOUT(msg) - - def errored(self): - spawn = self.spawn - spawn.before = spawn.buffer - spawn.after = None - spawn.match = None - spawn.match_index = None - - def expect_loop(self, timeout=-1): - """Blocking expect""" - spawn = self.spawn - - if timeout is not None: - end_time = time.time() + timeout - - try: - incoming = spawn.buffer - spawn._buffer = spawn.buffer_type() - spawn._before = spawn.buffer_type() - while True: - idx = self.new_data(incoming) - # Keep reading until exception or return. - if idx is not None: - return idx - # No match at this point - if (timeout is not None) and (timeout < 0): - return self.timeout() - # Still have time left, so read more data - incoming = spawn.read_nonblocking(spawn.maxread, timeout) - if self.spawn.delayafterread is not None: - time.sleep(self.spawn.delayafterread) - if timeout is not None: - timeout = end_time - time.time() - except EOF as e: - return self.eof(e) - except TIMEOUT as e: - return self.timeout(e) - except: - self.errored() - raise - - -class searcher_string(object): - '''This is a plain string search helper for the spawn.expect_any() method. - This helper class is for speed. For more powerful regex patterns - see the helper class, searcher_re. - - Attributes: - - eof_index - index of EOF, or -1 - timeout_index - index of TIMEOUT, or -1 - - After a successful match by the search() method the following attributes - are available: - - start - index into the buffer, first byte of match - end - index into the buffer, first byte after match - match - the matching string itself - - ''' - - def __init__(self, strings): - '''This creates an instance of searcher_string. This argument 'strings' - may be a list; a sequence of strings; or the EOF or TIMEOUT types. ''' - - self.eof_index = -1 - self.timeout_index = -1 - self._strings = [] - for n, s in enumerate(strings): - if s is EOF: - self.eof_index = n - continue - if s is TIMEOUT: - self.timeout_index = n - continue - self._strings.append((n, s)) - - def __str__(self): - '''This returns a human-readable string that represents the state of - the object.''' - - ss = [(ns[0], ' %d: %r' % ns) for ns in self._strings] - ss.append((-1, 'searcher_string:')) - if self.eof_index >= 0: - ss.append((self.eof_index, ' %d: EOF' % self.eof_index)) - if self.timeout_index >= 0: - ss.append((self.timeout_index, - ' %d: TIMEOUT' % self.timeout_index)) - ss.sort() - ss = list(zip(*ss))[1] - return '\n'.join(ss) - - def search(self, buffer, freshlen, searchwindowsize=None): - '''This searches 'buffer' for the first occurrence of one of the search - strings. 'freshlen' must indicate the number of bytes at the end of - 'buffer' which have not been searched before. It helps to avoid - searching the same, possibly big, buffer over and over again. - - See class spawn for the 'searchwindowsize' argument. - - If there is a match this returns the index of that string, and sets - 'start', 'end' and 'match'. Otherwise, this returns -1. ''' - - first_match = None - - # 'freshlen' helps a lot here. Further optimizations could - # possibly include: - # - # using something like the Boyer-Moore Fast String Searching - # Algorithm; pre-compiling the search through a list of - # strings into something that can scan the input once to - # search for all N strings; realize that if we search for - # ['bar', 'baz'] and the input is '...foo' we need not bother - # rescanning until we've read three more bytes. - # - # Sadly, I don't know enough about this interesting topic. /grahn - - for index, s in self._strings: - if searchwindowsize is None: - # the match, if any, can only be in the fresh data, - # or at the very end of the old data - offset = -(freshlen + len(s)) - else: - # better obey searchwindowsize - offset = -searchwindowsize - n = buffer.find(s, offset) - if n >= 0 and (first_match is None or n < first_match): - first_match = n - best_index, best_match = index, s - if first_match is None: - return -1 - self.match = best_match - self.start = first_match - self.end = self.start + len(self.match) - return best_index - - -class searcher_re(object): - '''This is regular expression string search helper for the - spawn.expect_any() method. This helper class is for powerful - pattern matching. For speed, see the helper class, searcher_string. - - Attributes: - - eof_index - index of EOF, or -1 - timeout_index - index of TIMEOUT, or -1 - - After a successful match by the search() method the following attributes - are available: - - start - index into the buffer, first byte of match - end - index into the buffer, first byte after match - match - the re.match object returned by a successful re.search - - ''' - - def __init__(self, patterns): - '''This creates an instance that searches for 'patterns' Where - 'patterns' may be a list or other sequence of compiled regular - expressions, or the EOF or TIMEOUT types.''' - - self.eof_index = -1 - self.timeout_index = -1 - self._searches = [] - for n, s in zip(list(range(len(patterns))), patterns): - if s is EOF: - self.eof_index = n - continue - if s is TIMEOUT: - self.timeout_index = n - continue - self._searches.append((n, s)) - - def __str__(self): - '''This returns a human-readable string that represents the state of - the object.''' - - #ss = [(n, ' %d: re.compile("%s")' % - # (n, repr(s.pattern))) for n, s in self._searches] - ss = list() - for n, s in self._searches: - ss.append((n, ' %d: re.compile(%r)' % (n, s.pattern))) - ss.append((-1, 'searcher_re:')) - if self.eof_index >= 0: - ss.append((self.eof_index, ' %d: EOF' % self.eof_index)) - if self.timeout_index >= 0: - ss.append((self.timeout_index, ' %d: TIMEOUT' % - self.timeout_index)) - ss.sort() - ss = list(zip(*ss))[1] - return '\n'.join(ss) - - def search(self, buffer, freshlen, searchwindowsize=None): - '''This searches 'buffer' for the first occurrence of one of the regular - expressions. 'freshlen' must indicate the number of bytes at the end of - 'buffer' which have not been searched before. - - See class spawn for the 'searchwindowsize' argument. - - If there is a match this returns the index of that string, and sets - 'start', 'end' and 'match'. Otherwise, returns -1.''' - - first_match = None - # 'freshlen' doesn't help here -- we cannot predict the - # length of a match, and the re module provides no help. - if searchwindowsize is None: - searchstart = 0 - else: - searchstart = max(0, len(buffer) - searchwindowsize) - for index, s in self._searches: - match = s.search(buffer, searchstart) - if match is None: - continue - n = match.start() - if first_match is None or n < first_match: - first_match = n - the_match = match - best_index = index - if first_match is None: - return -1 - self.start = first_match - self.match = the_match - self.end = self.match.end() - return best_index diff --git a/lldb/third_party/Python/module/pexpect-4.6/pexpect/fdpexpect.py b/lldb/third_party/Python/module/pexpect-4.6/pexpect/fdpexpect.py deleted file mode 100644 index cddd50e10058..000000000000 --- a/lldb/third_party/Python/module/pexpect-4.6/pexpect/fdpexpect.py +++ /dev/null @@ -1,148 +0,0 @@ -'''This is like pexpect, but it will work with any file descriptor that you -pass it. You are responsible for opening and close the file descriptor. -This allows you to use Pexpect with sockets and named pipes (FIFOs). - -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' - -from .spawnbase import SpawnBase -from .exceptions import ExceptionPexpect, TIMEOUT -from .utils import select_ignore_interrupts, poll_ignore_interrupts -import os - -__all__ = ['fdspawn'] - -class fdspawn(SpawnBase): - '''This is like pexpect.spawn but allows you to supply your own open file - descriptor. For example, you could use it to read through a file looking - for patterns, or to control a modem or serial device. ''' - - def __init__ (self, fd, args=None, timeout=30, maxread=2000, searchwindowsize=None, - logfile=None, encoding=None, codec_errors='strict', use_poll=False): - '''This takes a file descriptor (an int) or an object that support the - fileno() method (returning an int). All Python file-like objects - support fileno(). ''' - - if type(fd) != type(0) and hasattr(fd, 'fileno'): - fd = fd.fileno() - - if type(fd) != type(0): - raise ExceptionPexpect('The fd argument is not an int. If this is a command string then maybe you want to use pexpect.spawn.') - - try: # make sure fd is a valid file descriptor - os.fstat(fd) - except OSError: - raise ExceptionPexpect('The fd argument is not a valid file descriptor.') - - self.args = None - self.command = None - SpawnBase.__init__(self, timeout, maxread, searchwindowsize, logfile, - encoding=encoding, codec_errors=codec_errors) - self.child_fd = fd - self.own_fd = False - self.closed = False - self.name = '' % fd - self.use_poll = use_poll - - def close (self): - """Close the file descriptor. - - Calling this method a second time does nothing, but if the file - descriptor was closed elsewhere, :class:`OSError` will be raised. - """ - if self.child_fd == -1: - return - - self.flush() - os.close(self.child_fd) - self.child_fd = -1 - self.closed = True - - def isalive (self): - '''This checks if the file descriptor is still valid. If :func:`os.fstat` - does not raise an exception then we assume it is alive. ''' - - if self.child_fd == -1: - return False - try: - os.fstat(self.child_fd) - return True - except: - return False - - def terminate (self, force=False): # pragma: no cover - '''Deprecated and invalid. Just raises an exception.''' - raise ExceptionPexpect('This method is not valid for file descriptors.') - - # These four methods are left around for backwards compatibility, but not - # documented as part of fdpexpect. You're encouraged to use os.write - # directly. - def send(self, s): - "Write to fd, return number of bytes written" - s = self._coerce_send_string(s) - self._log(s, 'send') - - b = self._encoder.encode(s, final=False) - return os.write(self.child_fd, b) - - def sendline(self, s): - "Write to fd with trailing newline, return number of bytes written" - s = self._coerce_send_string(s) - return self.send(s + self.linesep) - - def write(self, s): - "Write to fd, return None" - self.send(s) - - def writelines(self, sequence): - "Call self.write() for each item in sequence" - for s in sequence: - self.write(s) - - def read_nonblocking(self, size=1, timeout=-1): - """ - Read from the file descriptor and return the result as a string. - - The read_nonblocking method of :class:`SpawnBase` assumes that a call - to os.read will not block (timeout parameter is ignored). This is not - the case for POSIX file-like objects such as sockets and serial ports. - - Use :func:`select.select`, timeout is implemented conditionally for - POSIX systems. - - :param int size: Read at most *size* bytes. - :param int timeout: Wait timeout seconds for file descriptor to be - ready to read. When -1 (default), use self.timeout. When 0, poll. - :return: String containing the bytes read - """ - if os.name == 'posix': - if timeout == -1: - timeout = self.timeout - rlist = [self.child_fd] - wlist = [] - xlist = [] - if self.use_poll: - rlist = poll_ignore_interrupts(rlist, timeout) - else: - rlist, wlist, xlist = select_ignore_interrupts( - rlist, wlist, xlist, timeout - ) - if self.child_fd not in rlist: - raise TIMEOUT('Timeout exceeded.') - return super(fdspawn, self).read_nonblocking(size) diff --git a/lldb/third_party/Python/module/pexpect-4.6/pexpect/popen_spawn.py b/lldb/third_party/Python/module/pexpect-4.6/pexpect/popen_spawn.py deleted file mode 100644 index 4bb58cfe76c9..000000000000 --- a/lldb/third_party/Python/module/pexpect-4.6/pexpect/popen_spawn.py +++ /dev/null @@ -1,188 +0,0 @@ -"""Provides an interface like pexpect.spawn interface using subprocess.Popen -""" -import os -import threading -import subprocess -import sys -import time -import signal -import shlex - -try: - from queue import Queue, Empty # Python 3 -except ImportError: - from Queue import Queue, Empty # Python 2 - -from .spawnbase import SpawnBase, PY3 -from .exceptions import EOF -from .utils import string_types - -class PopenSpawn(SpawnBase): - def __init__(self, cmd, timeout=30, maxread=2000, searchwindowsize=None, - logfile=None, cwd=None, env=None, encoding=None, - codec_errors='strict', preexec_fn=None): - super(PopenSpawn, self).__init__(timeout=timeout, maxread=maxread, - searchwindowsize=searchwindowsize, logfile=logfile, - encoding=encoding, codec_errors=codec_errors) - - # Note that `SpawnBase` initializes `self.crlf` to `\r\n` - # because the default behaviour for a PTY is to convert - # incoming LF to `\r\n` (see the `onlcr` flag and - # https://stackoverflow.com/a/35887657/5397009). Here we set - # it to `os.linesep` because that is what the spawned - # application outputs by default and `popen` doesn't translate - # anything. - if encoding is None: - self.crlf = os.linesep.encode ("ascii") - else: - self.crlf = self.string_type (os.linesep) - - kwargs = dict(bufsize=0, stdin=subprocess.PIPE, - stderr=subprocess.STDOUT, stdout=subprocess.PIPE, - cwd=cwd, preexec_fn=preexec_fn, env=env) - - if sys.platform == 'win32': - startupinfo = subprocess.STARTUPINFO() - startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW - kwargs['startupinfo'] = startupinfo - kwargs['creationflags'] = subprocess.CREATE_NEW_PROCESS_GROUP - - if isinstance(cmd, string_types) and sys.platform != 'win32': - cmd = shlex.split(cmd, posix=os.name == 'posix') - - self.proc = subprocess.Popen(cmd, **kwargs) - self.pid = self.proc.pid - self.closed = False - self._buf = self.string_type() - - self._read_queue = Queue() - self._read_thread = threading.Thread(target=self._read_incoming) - self._read_thread.setDaemon(True) - self._read_thread.start() - - _read_reached_eof = False - - def read_nonblocking(self, size, timeout): - buf = self._buf - if self._read_reached_eof: - # We have already finished reading. Use up any buffered data, - # then raise EOF - if buf: - self._buf = buf[size:] - return buf[:size] - else: - self.flag_eof = True - raise EOF('End Of File (EOF).') - - if timeout == -1: - timeout = self.timeout - elif timeout is None: - timeout = 1e6 - - t0 = time.time() - while (time.time() - t0) < timeout and size and len(buf) < size: - try: - incoming = self._read_queue.get_nowait() - except Empty: - break - else: - if incoming is None: - self._read_reached_eof = True - break - - buf += self._decoder.decode(incoming, final=False) - - r, self._buf = buf[:size], buf[size:] - - self._log(r, 'read') - return r - - def _read_incoming(self): - """Run in a thread to move output from a pipe to a queue.""" - fileno = self.proc.stdout.fileno() - while 1: - buf = b'' - try: - buf = os.read(fileno, 1024) - except OSError as e: - self._log(e, 'read') - - if not buf: - # This indicates we have reached EOF - self._read_queue.put(None) - return - - self._read_queue.put(buf) - - def write(self, s): - '''This is similar to send() except that there is no return value. - ''' - self.send(s) - - def writelines(self, sequence): - '''This calls write() for each element in the sequence. - - The sequence can be any iterable object producing strings, typically a - list of strings. This does not add line separators. There is no return - value. - ''' - for s in sequence: - self.send(s) - - def send(self, s): - '''Send data to the subprocess' stdin. - - Returns the number of bytes written. - ''' - s = self._coerce_send_string(s) - self._log(s, 'send') - - b = self._encoder.encode(s, final=False) - if PY3: - return self.proc.stdin.write(b) - else: - # On Python 2, .write() returns None, so we return the length of - # bytes written ourselves. This assumes they all got written. - self.proc.stdin.write(b) - return len(b) - - def sendline(self, s=''): - '''Wraps send(), sending string ``s`` to child process, with os.linesep - automatically appended. Returns number of bytes written. ''' - - n = self.send(s) - return n + self.send(self.linesep) - - def wait(self): - '''Wait for the subprocess to finish. - - Returns the exit code. - ''' - status = self.proc.wait() - if status >= 0: - self.exitstatus = status - self.signalstatus = None - else: - self.exitstatus = None - self.signalstatus = -status - self.terminated = True - return status - - def kill(self, sig): - '''Sends a Unix signal to the subprocess. - - Use constants from the :mod:`signal` module to specify which signal. - ''' - if sys.platform == 'win32': - if sig in [signal.SIGINT, signal.CTRL_C_EVENT]: - sig = signal.CTRL_C_EVENT - elif sig in [signal.SIGBREAK, signal.CTRL_BREAK_EVENT]: - sig = signal.CTRL_BREAK_EVENT - else: - sig = signal.SIGTERM - - os.kill(self.proc.pid, sig) - - def sendeof(self): - '''Closes the stdin pipe from the writing end.''' - self.proc.stdin.close() diff --git a/lldb/third_party/Python/module/pexpect-4.6/pexpect/pty_spawn.py b/lldb/third_party/Python/module/pexpect-4.6/pexpect/pty_spawn.py deleted file mode 100644 index 6b9ad3f63f7c..000000000000 --- a/lldb/third_party/Python/module/pexpect-4.6/pexpect/pty_spawn.py +++ /dev/null @@ -1,833 +0,0 @@ -import os -import sys -import time -import pty -import tty -import errno -import signal -from contextlib import contextmanager - -import ptyprocess -from ptyprocess.ptyprocess import use_native_pty_fork - -from .exceptions import ExceptionPexpect, EOF, TIMEOUT -from .spawnbase import SpawnBase -from .utils import ( - which, split_command_line, select_ignore_interrupts, poll_ignore_interrupts -) - -@contextmanager -def _wrap_ptyprocess_err(): - """Turn ptyprocess errors into our own ExceptionPexpect errors""" - try: - yield - except ptyprocess.PtyProcessError as e: - raise ExceptionPexpect(*e.args) - -PY3 = (sys.version_info[0] >= 3) - -class spawn(SpawnBase): - '''This is the main class interface for Pexpect. Use this class to start - and control child applications. ''' - - # This is purely informational now - changing it has no effect - use_native_pty_fork = use_native_pty_fork - - def __init__(self, command, args=[], timeout=30, maxread=2000, - searchwindowsize=None, logfile=None, cwd=None, env=None, - ignore_sighup=False, echo=True, preexec_fn=None, - encoding=None, codec_errors='strict', dimensions=None, - use_poll=False): - '''This is the constructor. The command parameter may be a string that - includes a command and any arguments to the command. For example:: - - child = pexpect.spawn('/usr/bin/ftp') - child = pexpect.spawn('/usr/bin/ssh user@example.com') - child = pexpect.spawn('ls -latr /tmp') - - You may also construct it with a list of arguments like so:: - - child = pexpect.spawn('/usr/bin/ftp', []) - child = pexpect.spawn('/usr/bin/ssh', ['user@example.com']) - child = pexpect.spawn('ls', ['-latr', '/tmp']) - - After this the child application will be created and will be ready to - talk to. For normal use, see expect() and send() and sendline(). - - Remember that Pexpect does NOT interpret shell meta characters such as - redirect, pipe, or wild cards (``>``, ``|``, or ``*``). This is a - common mistake. If you want to run a command and pipe it through - another command then you must also start a shell. For example:: - - child = pexpect.spawn('/bin/bash -c "ls -l | grep LOG > logs.txt"') - child.expect(pexpect.EOF) - - The second form of spawn (where you pass a list of arguments) is useful - in situations where you wish to spawn a command and pass it its own - argument list. This can make syntax more clear. For example, the - following is equivalent to the previous example:: - - shell_cmd = 'ls -l | grep LOG > logs.txt' - child = pexpect.spawn('/bin/bash', ['-c', shell_cmd]) - child.expect(pexpect.EOF) - - The maxread attribute sets the read buffer size. This is maximum number - of bytes that Pexpect will try to read from a TTY at one time. Setting - the maxread size to 1 will turn off buffering. Setting the maxread - value higher may help performance in cases where large amounts of - output are read back from the child. This feature is useful in - conjunction with searchwindowsize. - - When the keyword argument *searchwindowsize* is None (default), the - full buffer is searched at each iteration of receiving incoming data. - The default number of bytes scanned at each iteration is very large - and may be reduced to collaterally reduce search cost. After - :meth:`~.expect` returns, the full buffer attribute remains up to - size *maxread* irrespective of *searchwindowsize* value. - - When the keyword argument ``timeout`` is specified as a number, - (default: *30*), then :class:`TIMEOUT` will be raised after the value - specified has elapsed, in seconds, for any of the :meth:`~.expect` - family of method calls. When None, TIMEOUT will not be raised, and - :meth:`~.expect` may block indefinitely until match. - - - The logfile member turns on or off logging. All input and output will - be copied to the given file object. Set logfile to None to stop - logging. This is the default. Set logfile to sys.stdout to echo - everything to standard output. The logfile is flushed after each write. - - Example log input and output to a file:: - - child = pexpect.spawn('some_command') - fout = open('mylog.txt','wb') - child.logfile = fout - - Example log to stdout:: - - # In Python 2: - child = pexpect.spawn('some_command') - child.logfile = sys.stdout - - # In Python 3, we'll use the ``encoding`` argument to decode data - # from the subprocess and handle it as unicode: - child = pexpect.spawn('some_command', encoding='utf-8') - child.logfile = sys.stdout - - The logfile_read and logfile_send members can be used to separately log - the input from the child and output sent to the child. Sometimes you - don't want to see everything you write to the child. You only want to - log what the child sends back. For example:: - - child = pexpect.spawn('some_command') - child.logfile_read = sys.stdout - - You will need to pass an encoding to spawn in the above code if you are - using Python 3. - - To separately log output sent to the child use logfile_send:: - - child.logfile_send = fout - - If ``ignore_sighup`` is True, the child process will ignore SIGHUP - signals. The default is False from Pexpect 4.0, meaning that SIGHUP - will be handled normally by the child. - - The delaybeforesend helps overcome a weird behavior that many users - were experiencing. The typical problem was that a user would expect() a - "Password:" prompt and then immediately call sendline() to send the - password. The user would then see that their password was echoed back - to them. Passwords don't normally echo. The problem is caused by the - fact that most applications print out the "Password" prompt and then - turn off stdin echo, but if you send your password before the - application turned off echo, then you get your password echoed. - Normally this wouldn't be a problem when interacting with a human at a - real keyboard. If you introduce a slight delay just before writing then - this seems to clear up the problem. This was such a common problem for - many users that I decided that the default pexpect behavior should be - to sleep just before writing to the child application. 1/20th of a - second (50 ms) seems to be enough to clear up the problem. You can set - delaybeforesend to None to return to the old behavior. - - Note that spawn is clever about finding commands on your path. - It uses the same logic that "which" uses to find executables. - - If you wish to get the exit status of the child you must call the - close() method. The exit or signal status of the child will be stored - in self.exitstatus or self.signalstatus. If the child exited normally - then exitstatus will store the exit return code and signalstatus will - be None. If the child was terminated abnormally with a signal then - signalstatus will store the signal value and exitstatus will be None:: - - child = pexpect.spawn('some_command') - child.close() - print(child.exitstatus, child.signalstatus) - - If you need more detail you can also read the self.status member which - stores the status returned by os.waitpid. You can interpret this using - os.WIFEXITED/os.WEXITSTATUS or os.WIFSIGNALED/os.TERMSIG. - - The echo attribute may be set to False to disable echoing of input. - As a pseudo-terminal, all input echoed by the "keyboard" (send() - or sendline()) will be repeated to output. For many cases, it is - not desirable to have echo enabled, and it may be later disabled - using setecho(False) followed by waitnoecho(). However, for some - platforms such as Solaris, this is not possible, and should be - disabled immediately on spawn. - - If preexec_fn is given, it will be called in the child process before - launching the given command. This is useful to e.g. reset inherited - signal handlers. - - The dimensions attribute specifies the size of the pseudo-terminal as - seen by the subprocess, and is specified as a two-entry tuple (rows, - columns). If this is unspecified, the defaults in ptyprocess will apply. - - The use_poll attribute enables using select.poll() over select.select() - for socket handling. This is handy if your system could have > 1024 fds - ''' - super(spawn, self).__init__(timeout=timeout, maxread=maxread, searchwindowsize=searchwindowsize, - logfile=logfile, encoding=encoding, codec_errors=codec_errors) - self.STDIN_FILENO = pty.STDIN_FILENO - self.STDOUT_FILENO = pty.STDOUT_FILENO - self.STDERR_FILENO = pty.STDERR_FILENO - self.cwd = cwd - self.env = env - self.echo = echo - self.ignore_sighup = ignore_sighup - self.__irix_hack = sys.platform.lower().startswith('irix') - if command is None: - self.command = None - self.args = None - self.name = '' - else: - self._spawn(command, args, preexec_fn, dimensions) - self.use_poll = use_poll - - def __str__(self): - '''This returns a human-readable string that represents the state of - the object. ''' - - s = [] - s.append(repr(self)) - s.append('command: ' + str(self.command)) - s.append('args: %r' % (self.args,)) - s.append('buffer (last 100 chars): %r' % self.buffer[-100:]) - s.append('before (last 100 chars): %r' % self.before[-100:] if self.before else '') - s.append('after: %r' % (self.after,)) - s.append('match: %r' % (self.match,)) - s.append('match_index: ' + str(self.match_index)) - s.append('exitstatus: ' + str(self.exitstatus)) - if hasattr(self, 'ptyproc'): - s.append('flag_eof: ' + str(self.flag_eof)) - s.append('pid: ' + str(self.pid)) - s.append('child_fd: ' + str(self.child_fd)) - s.append('closed: ' + str(self.closed)) - s.append('timeout: ' + str(self.timeout)) - s.append('delimiter: ' + str(self.delimiter)) - s.append('logfile: ' + str(self.logfile)) - s.append('logfile_read: ' + str(self.logfile_read)) - s.append('logfile_send: ' + str(self.logfile_send)) - s.append('maxread: ' + str(self.maxread)) - s.append('ignorecase: ' + str(self.ignorecase)) - s.append('searchwindowsize: ' + str(self.searchwindowsize)) - s.append('delaybeforesend: ' + str(self.delaybeforesend)) - s.append('delayafterclose: ' + str(self.delayafterclose)) - s.append('delayafterterminate: ' + str(self.delayafterterminate)) - return '\n'.join(s) - - def _spawn(self, command, args=[], preexec_fn=None, dimensions=None): - '''This starts the given command in a child process. This does all the - fork/exec type of stuff for a pty. This is called by __init__. If args - is empty then command will be parsed (split on spaces) and args will be - set to parsed arguments. ''' - - # The pid and child_fd of this object get set by this method. - # Note that it is difficult for this method to fail. - # You cannot detect if the child process cannot start. - # So the only way you can tell if the child process started - # or not is to try to read from the file descriptor. If you get - # EOF immediately then it means that the child is already dead. - # That may not necessarily be bad because you may have spawned a child - # that performs some task; creates no stdout output; and then dies. - - # If command is an int type then it may represent a file descriptor. - if isinstance(command, type(0)): - raise ExceptionPexpect('Command is an int type. ' + - 'If this is a file descriptor then maybe you want to ' + - 'use fdpexpect.fdspawn which takes an existing ' + - 'file descriptor instead of a command string.') - - if not isinstance(args, type([])): - raise TypeError('The argument, args, must be a list.') - - if args == []: - self.args = split_command_line(command) - self.command = self.args[0] - else: - # Make a shallow copy of the args list. - self.args = args[:] - self.args.insert(0, command) - self.command = command - - command_with_path = which(self.command, env=self.env) - if command_with_path is None: - raise ExceptionPexpect('The command was not found or was not ' + - 'executable: %s.' % self.command) - self.command = command_with_path - self.args[0] = self.command - - self.name = '<' + ' '.join(self.args) + '>' - - assert self.pid is None, 'The pid member must be None.' - assert self.command is not None, 'The command member must not be None.' - - kwargs = {'echo': self.echo, 'preexec_fn': preexec_fn} - if self.ignore_sighup: - def preexec_wrapper(): - "Set SIGHUP to be ignored, then call the real preexec_fn" - signal.signal(signal.SIGHUP, signal.SIG_IGN) - if preexec_fn is not None: - preexec_fn() - kwargs['preexec_fn'] = preexec_wrapper - - if dimensions is not None: - kwargs['dimensions'] = dimensions - - if self.encoding is not None: - # Encode command line using the specified encoding - self.args = [a if isinstance(a, bytes) else a.encode(self.encoding) - for a in self.args] - - self.ptyproc = self._spawnpty(self.args, env=self.env, - cwd=self.cwd, **kwargs) - - self.pid = self.ptyproc.pid - self.child_fd = self.ptyproc.fd - - - self.terminated = False - self.closed = False - - def _spawnpty(self, args, **kwargs): - '''Spawn a pty and return an instance of PtyProcess.''' - return ptyprocess.PtyProcess.spawn(args, **kwargs) - - def close(self, force=True): - '''This closes the connection with the child application. Note that - calling close() more than once is valid. This emulates standard Python - behavior with files. Set force to True if you want to make sure that - the child is terminated (SIGKILL is sent if the child ignores SIGHUP - and SIGINT). ''' - - self.flush() - with _wrap_ptyprocess_err(): - # PtyProcessError may be raised if it is not possible to terminate - # the child. - self.ptyproc.close(force=force) - self.isalive() # Update exit status from ptyproc - self.child_fd = -1 - self.closed = True - - def isatty(self): - '''This returns True if the file descriptor is open and connected to a - tty(-like) device, else False. - - On SVR4-style platforms implementing streams, such as SunOS and HP-UX, - the child pty may not appear as a terminal device. This means - methods such as setecho(), setwinsize(), getwinsize() may raise an - IOError. ''' - - return os.isatty(self.child_fd) - - def waitnoecho(self, timeout=-1): - '''This waits until the terminal ECHO flag is set False. This returns - True if the echo mode is off. This returns False if the ECHO flag was - not set False before the timeout. This can be used to detect when the - child is waiting for a password. Usually a child application will turn - off echo mode when it is waiting for the user to enter a password. For - example, instead of expecting the "password:" prompt you can wait for - the child to set ECHO off:: - - p = pexpect.spawn('ssh user@example.com') - p.waitnoecho() - p.sendline(mypassword) - - If timeout==-1 then this method will use the value in self.timeout. - If timeout==None then this method to block until ECHO flag is False. - ''' - - if timeout == -1: - timeout = self.timeout - if timeout is not None: - end_time = time.time() + timeout - while True: - if not self.getecho(): - return True - if timeout < 0 and timeout is not None: - return False - if timeout is not None: - timeout = end_time - time.time() - time.sleep(0.1) - - def getecho(self): - '''This returns the terminal echo mode. This returns True if echo is - on or False if echo is off. Child applications that are expecting you - to enter a password often set ECHO False. See waitnoecho(). - - Not supported on platforms where ``isatty()`` returns False. ''' - return self.ptyproc.getecho() - - def setecho(self, state): - '''This sets the terminal echo mode on or off. Note that anything the - child sent before the echo will be lost, so you should be sure that - your input buffer is empty before you call setecho(). For example, the - following will work as expected:: - - p = pexpect.spawn('cat') # Echo is on by default. - p.sendline('1234') # We expect see this twice from the child... - p.expect(['1234']) # ... once from the tty echo... - p.expect(['1234']) # ... and again from cat itself. - p.setecho(False) # Turn off tty echo - p.sendline('abcd') # We will set this only once (echoed by cat). - p.sendline('wxyz') # We will set this only once (echoed by cat) - p.expect(['abcd']) - p.expect(['wxyz']) - - The following WILL NOT WORK because the lines sent before the setecho - will be lost:: - - p = pexpect.spawn('cat') - p.sendline('1234') - p.setecho(False) # Turn off tty echo - p.sendline('abcd') # We will set this only once (echoed by cat). - p.sendline('wxyz') # We will set this only once (echoed by cat) - p.expect(['1234']) - p.expect(['1234']) - p.expect(['abcd']) - p.expect(['wxyz']) - - - Not supported on platforms where ``isatty()`` returns False. - ''' - return self.ptyproc.setecho(state) - - def read_nonblocking(self, size=1, timeout=-1): - '''This reads at most size characters from the child application. It - includes a timeout. If the read does not complete within the timeout - period then a TIMEOUT exception is raised. If the end of file is read - then an EOF exception will be raised. If a logfile is specified, a - copy is written to that log. - - If timeout is None then the read may block indefinitely. - If timeout is -1 then the self.timeout value is used. If timeout is 0 - then the child is polled and if there is no data immediately ready - then this will raise a TIMEOUT exception. - - The timeout refers only to the amount of time to read at least one - character. This is not affected by the 'size' parameter, so if you call - read_nonblocking(size=100, timeout=30) and only one character is - available right away then one character will be returned immediately. - It will not wait for 30 seconds for another 99 characters to come in. - - This is a wrapper around os.read(). It uses select.select() to - implement the timeout. ''' - - if self.closed: - raise ValueError('I/O operation on closed file.') - - if timeout == -1: - timeout = self.timeout - - # Note that some systems such as Solaris do not give an EOF when - # the child dies. In fact, you can still try to read - # from the child_fd -- it will block forever or until TIMEOUT. - # For this case, I test isalive() before doing any reading. - # If isalive() is false, then I pretend that this is the same as EOF. - if not self.isalive(): - # timeout of 0 means "poll" - if self.use_poll: - r = poll_ignore_interrupts([self.child_fd], timeout) - else: - r, w, e = select_ignore_interrupts([self.child_fd], [], [], 0) - if not r: - self.flag_eof = True - raise EOF('End Of File (EOF). Braindead platform.') - elif self.__irix_hack: - # Irix takes a long time before it realizes a child was terminated. - # FIXME So does this mean Irix systems are forced to always have - # FIXME a 2 second delay when calling read_nonblocking? That sucks. - if self.use_poll: - r = poll_ignore_interrupts([self.child_fd], timeout) - else: - r, w, e = select_ignore_interrupts([self.child_fd], [], [], 2) - if not r and not self.isalive(): - self.flag_eof = True - raise EOF('End Of File (EOF). Slow platform.') - if self.use_poll: - r = poll_ignore_interrupts([self.child_fd], timeout) - else: - r, w, e = select_ignore_interrupts( - [self.child_fd], [], [], timeout - ) - - if not r: - if not self.isalive(): - # Some platforms, such as Irix, will claim that their - # processes are alive; timeout on the select; and - # then finally admit that they are not alive. - self.flag_eof = True - raise EOF('End of File (EOF). Very slow platform.') - else: - raise TIMEOUT('Timeout exceeded.') - - if self.child_fd in r: - return super(spawn, self).read_nonblocking(size) - - raise ExceptionPexpect('Reached an unexpected state.') # pragma: no cover - - def write(self, s): - '''This is similar to send() except that there is no return value. - ''' - - self.send(s) - - def writelines(self, sequence): - '''This calls write() for each element in the sequence. The sequence - can be any iterable object producing strings, typically a list of - strings. This does not add line separators. There is no return value. - ''' - - for s in sequence: - self.write(s) - - def send(self, s): - '''Sends string ``s`` to the child process, returning the number of - bytes written. If a logfile is specified, a copy is written to that - log. - - The default terminal input mode is canonical processing unless set - otherwise by the child process. This allows backspace and other line - processing to be performed prior to transmitting to the receiving - program. As this is buffered, there is a limited size of such buffer. - - On Linux systems, this is 4096 (defined by N_TTY_BUF_SIZE). All - other systems honor the POSIX.1 definition PC_MAX_CANON -- 1024 - on OSX, 256 on OpenSolaris, and 1920 on FreeBSD. - - This value may be discovered using fpathconf(3):: - - >>> from os import fpathconf - >>> print(fpathconf(0, 'PC_MAX_CANON')) - 256 - - On such a system, only 256 bytes may be received per line. Any - subsequent bytes received will be discarded. BEL (``'\a'``) is then - sent to output if IMAXBEL (termios.h) is set by the tty driver. - This is usually enabled by default. Linux does not honor this as - an option -- it behaves as though it is always set on. - - Canonical input processing may be disabled altogether by executing - a shell, then stty(1), before executing the final program:: - - >>> bash = pexpect.spawn('/bin/bash', echo=False) - >>> bash.sendline('stty -icanon') - >>> bash.sendline('base64') - >>> bash.sendline('x' * 5000) - ''' - - if self.delaybeforesend is not None: - time.sleep(self.delaybeforesend) - - s = self._coerce_send_string(s) - self._log(s, 'send') - - b = self._encoder.encode(s, final=False) - return os.write(self.child_fd, b) - - def sendline(self, s=''): - '''Wraps send(), sending string ``s`` to child process, with - ``os.linesep`` automatically appended. Returns number of bytes - written. Only a limited number of bytes may be sent for each - line in the default terminal mode, see docstring of :meth:`send`. - ''' - s = self._coerce_send_string(s) - return self.send(s + self.linesep) - - def _log_control(self, s): - """Write control characters to the appropriate log files""" - if self.encoding is not None: - s = s.decode(self.encoding, 'replace') - self._log(s, 'send') - - def sendcontrol(self, char): - '''Helper method that wraps send() with mnemonic access for sending control - character to the child (such as Ctrl-C or Ctrl-D). For example, to send - Ctrl-G (ASCII 7, bell, '\a'):: - - child.sendcontrol('g') - - See also, sendintr() and sendeof(). - ''' - n, byte = self.ptyproc.sendcontrol(char) - self._log_control(byte) - return n - - def sendeof(self): - '''This sends an EOF to the child. This sends a character which causes - the pending parent output buffer to be sent to the waiting child - program without waiting for end-of-line. If it is the first character - of the line, the read() in the user program returns 0, which signifies - end-of-file. This means to work as expected a sendeof() has to be - called at the beginning of a line. This method does not send a newline. - It is the responsibility of the caller to ensure the eof is sent at the - beginning of a line. ''' - - n, byte = self.ptyproc.sendeof() - self._log_control(byte) - - def sendintr(self): - '''This sends a SIGINT to the child. It does not require - the SIGINT to be the first character on a line. ''' - - n, byte = self.ptyproc.sendintr() - self._log_control(byte) - - @property - def flag_eof(self): - return self.ptyproc.flag_eof - - @flag_eof.setter - def flag_eof(self, value): - self.ptyproc.flag_eof = value - - def eof(self): - '''This returns True if the EOF exception was ever raised. - ''' - return self.flag_eof - - def terminate(self, force=False): - '''This forces a child process to terminate. It starts nicely with - SIGHUP and SIGINT. If "force" is True then moves onto SIGKILL. This - returns True if the child was terminated. This returns False if the - child could not be terminated. ''' - - if not self.isalive(): - return True - try: - self.kill(signal.SIGHUP) - time.sleep(self.delayafterterminate) - if not self.isalive(): - return True - self.kill(signal.SIGCONT) - time.sleep(self.delayafterterminate) - if not self.isalive(): - return True - self.kill(signal.SIGINT) - time.sleep(self.delayafterterminate) - if not self.isalive(): - return True - if force: - self.kill(signal.SIGKILL) - time.sleep(self.delayafterterminate) - if not self.isalive(): - return True - else: - return False - return False - except OSError: - # I think there are kernel timing issues that sometimes cause - # this to happen. I think isalive() reports True, but the - # process is dead to the kernel. - # Make one last attempt to see if the kernel is up to date. - time.sleep(self.delayafterterminate * 10) - if not self.isalive(): - return True - else: - return False - - def wait(self): - '''This waits until the child exits. This is a blocking call. This will - not read any data from the child, so this will block forever if the - child has unread output and has terminated. In other words, the child - may have printed output then called exit(), but, the child is - technically still alive until its output is read by the parent. - - This method is non-blocking if :meth:`wait` has already been called - previously or :meth:`isalive` method returns False. It simply returns - the previously determined exit status. - ''' - - ptyproc = self.ptyproc - with _wrap_ptyprocess_err(): - # exception may occur if "Is some other process attempting - # "job control with our child pid?" - exitstatus = ptyproc.wait() - self.status = ptyproc.status - self.exitstatus = ptyproc.exitstatus - self.signalstatus = ptyproc.signalstatus - self.terminated = True - - return exitstatus - - def isalive(self): - '''This tests if the child process is running or not. This is - non-blocking. If the child was terminated then this will read the - exitstatus or signalstatus of the child. This returns True if the child - process appears to be running or False if not. It can take literally - SECONDS for Solaris to return the right status. ''' - - ptyproc = self.ptyproc - with _wrap_ptyprocess_err(): - alive = ptyproc.isalive() - - if not alive: - self.status = ptyproc.status - self.exitstatus = ptyproc.exitstatus - self.signalstatus = ptyproc.signalstatus - self.terminated = True - - return alive - - def kill(self, sig): - - '''This sends the given signal to the child application. In keeping - with UNIX tradition it has a misleading name. It does not necessarily - kill the child unless you send the right signal. ''' - - # Same as os.kill, but the pid is given for you. - if self.isalive(): - os.kill(self.pid, sig) - - def getwinsize(self): - '''This returns the terminal window size of the child tty. The return - value is a tuple of (rows, cols). ''' - return self.ptyproc.getwinsize() - - def setwinsize(self, rows, cols): - '''This sets the terminal window size of the child tty. This will cause - a SIGWINCH signal to be sent to the child. This does not change the - physical window size. It changes the size reported to TTY-aware - applications like vi or curses -- applications that respond to the - SIGWINCH signal. ''' - return self.ptyproc.setwinsize(rows, cols) - - - def interact(self, escape_character=chr(29), - input_filter=None, output_filter=None): - - '''This gives control of the child process to the interactive user (the - human at the keyboard). Keystrokes are sent to the child process, and - the stdout and stderr output of the child process is printed. This - simply echos the child stdout and child stderr to the real stdout and - it echos the real stdin to the child stdin. When the user types the - escape_character this method will return None. The escape_character - will not be transmitted. The default for escape_character is - entered as ``Ctrl - ]``, the very same as BSD telnet. To prevent - escaping, escape_character may be set to None. - - If a logfile is specified, then the data sent and received from the - child process in interact mode is duplicated to the given log. - - You may pass in optional input and output filter functions. These - functions should take a string and return a string. The output_filter - will be passed all the output from the child process. The input_filter - will be passed all the keyboard input from the user. The input_filter - is run BEFORE the check for the escape_character. - - Note that if you change the window size of the parent the SIGWINCH - signal will not be passed through to the child. If you want the child - window size to change when the parent's window size changes then do - something like the following example:: - - import pexpect, struct, fcntl, termios, signal, sys - def sigwinch_passthrough (sig, data): - s = struct.pack("HHHH", 0, 0, 0, 0) - a = struct.unpack('hhhh', fcntl.ioctl(sys.stdout.fileno(), - termios.TIOCGWINSZ , s)) - if not p.closed: - p.setwinsize(a[0],a[1]) - - # Note this 'p' is global and used in sigwinch_passthrough. - p = pexpect.spawn('/bin/bash') - signal.signal(signal.SIGWINCH, sigwinch_passthrough) - p.interact() - ''' - - # Flush the buffer. - self.write_to_stdout(self.buffer) - self.stdout.flush() - self._buffer = self.buffer_type() - mode = tty.tcgetattr(self.STDIN_FILENO) - tty.setraw(self.STDIN_FILENO) - if escape_character is not None and PY3: - escape_character = escape_character.encode('latin-1') - try: - self.__interact_copy(escape_character, input_filter, output_filter) - finally: - tty.tcsetattr(self.STDIN_FILENO, tty.TCSAFLUSH, mode) - - def __interact_writen(self, fd, data): - '''This is used by the interact() method. - ''' - - while data != b'' and self.isalive(): - n = os.write(fd, data) - data = data[n:] - - def __interact_read(self, fd): - '''This is used by the interact() method. - ''' - - return os.read(fd, 1000) - - def __interact_copy( - self, escape_character=None, input_filter=None, output_filter=None - ): - - '''This is used by the interact() method. - ''' - - while self.isalive(): - if self.use_poll: - r = poll_ignore_interrupts([self.child_fd, self.STDIN_FILENO]) - else: - r, w, e = select_ignore_interrupts( - [self.child_fd, self.STDIN_FILENO], [], [] - ) - if self.child_fd in r: - try: - data = self.__interact_read(self.child_fd) - except OSError as err: - if err.args[0] == errno.EIO: - # Linux-style EOF - break - raise - if data == b'': - # BSD-style EOF - break - if output_filter: - data = output_filter(data) - self._log(data, 'read') - os.write(self.STDOUT_FILENO, data) - if self.STDIN_FILENO in r: - data = self.__interact_read(self.STDIN_FILENO) - if input_filter: - data = input_filter(data) - i = -1 - if escape_character is not None: - i = data.rfind(escape_character) - if i != -1: - data = data[:i] - if data: - self._log(data, 'send') - self.__interact_writen(self.child_fd, data) - break - self._log(data, 'send') - self.__interact_writen(self.child_fd, data) - - -def spawnu(*args, **kwargs): - """Deprecated: pass encoding to spawn() instead.""" - kwargs.setdefault('encoding', 'utf-8') - return spawn(*args, **kwargs) diff --git a/lldb/third_party/Python/module/pexpect-4.6/pexpect/pxssh.py b/lldb/third_party/Python/module/pexpect-4.6/pexpect/pxssh.py deleted file mode 100644 index ef2e91186b37..000000000000 --- a/lldb/third_party/Python/module/pexpect-4.6/pexpect/pxssh.py +++ /dev/null @@ -1,499 +0,0 @@ -'''This class extends pexpect.spawn to specialize setting up SSH connections. -This adds methods for login, logout, and expecting the shell prompt. - -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' - -from pexpect import ExceptionPexpect, TIMEOUT, EOF, spawn -import time -import os -import sys -import re - -__all__ = ['ExceptionPxssh', 'pxssh'] - -# Exception classes used by this module. -class ExceptionPxssh(ExceptionPexpect): - '''Raised for pxssh exceptions. - ''' - -if sys.version_info > (3, 0): - from shlex import quote -else: - _find_unsafe = re.compile(r'[^\w@%+=:,./-]').search - - def quote(s): - """Return a shell-escaped version of the string *s*.""" - if not s: - return "''" - if _find_unsafe(s) is None: - return s - - # use single quotes, and put single quotes into double quotes - # the string $'b is then quoted as '$'"'"'b' - return "'" + s.replace("'", "'\"'\"'") + "'" - -class pxssh (spawn): - '''This class extends pexpect.spawn to specialize setting up SSH - connections. This adds methods for login, logout, and expecting the shell - prompt. It does various tricky things to handle many situations in the SSH - login process. For example, if the session is your first login, then pxssh - automatically accepts the remote certificate; or if you have public key - authentication setup then pxssh won't wait for the password prompt. - - pxssh uses the shell prompt to synchronize output from the remote host. In - order to make this more robust it sets the shell prompt to something more - unique than just $ or #. This should work on most Borne/Bash or Csh style - shells. - - Example that runs a few commands on a remote server and prints the result:: - - from pexpect import pxssh - import getpass - try: - s = pxssh.pxssh() - hostname = raw_input('hostname: ') - username = raw_input('username: ') - password = getpass.getpass('password: ') - s.login(hostname, username, password) - s.sendline('uptime') # run a command - s.prompt() # match the prompt - print(s.before) # print everything before the prompt. - s.sendline('ls -l') - s.prompt() - print(s.before) - s.sendline('df') - s.prompt() - print(s.before) - s.logout() - except pxssh.ExceptionPxssh as e: - print("pxssh failed on login.") - print(e) - - Example showing how to specify SSH options:: - - from pexpect import pxssh - s = pxssh.pxssh(options={ - "StrictHostKeyChecking": "no", - "UserKnownHostsFile": "/dev/null"}) - ... - - Note that if you have ssh-agent running while doing development with pxssh - then this can lead to a lot of confusion. Many X display managers (xdm, - gdm, kdm, etc.) will automatically start a GUI agent. You may see a GUI - dialog box popup asking for a password during development. You should turn - off any key agents during testing. The 'force_password' attribute will turn - off public key authentication. This will only work if the remote SSH server - is configured to allow password logins. Example of using 'force_password' - attribute:: - - s = pxssh.pxssh() - s.force_password = True - hostname = raw_input('hostname: ') - username = raw_input('username: ') - password = getpass.getpass('password: ') - s.login (hostname, username, password) - - `debug_command_string` is only for the test suite to confirm that the string - generated for SSH is correct, using this will not allow you to do - anything other than get a string back from `pxssh.pxssh.login()`. - ''' - - def __init__ (self, timeout=30, maxread=2000, searchwindowsize=None, - logfile=None, cwd=None, env=None, ignore_sighup=True, echo=True, - options={}, encoding=None, codec_errors='strict', - debug_command_string=False): - - spawn.__init__(self, None, timeout=timeout, maxread=maxread, - searchwindowsize=searchwindowsize, logfile=logfile, - cwd=cwd, env=env, ignore_sighup=ignore_sighup, echo=echo, - encoding=encoding, codec_errors=codec_errors) - - self.name = '' - - #SUBTLE HACK ALERT! Note that the command that SETS the prompt uses a - #slightly different string than the regular expression to match it. This - #is because when you set the prompt the command will echo back, but we - #don't want to match the echoed command. So if we make the set command - #slightly different than the regex we eliminate the problem. To make the - #set command different we add a backslash in front of $. The $ doesn't - #need to be escaped, but it doesn't hurt and serves to make the set - #prompt command different than the regex. - - # used to match the command-line prompt - self.UNIQUE_PROMPT = r"\[PEXPECT\][\$\#] " - self.PROMPT = self.UNIQUE_PROMPT - - # used to set shell command-line prompt to UNIQUE_PROMPT. - self.PROMPT_SET_SH = r"PS1='[PEXPECT]\$ '" - self.PROMPT_SET_CSH = r"set prompt='[PEXPECT]\$ '" - self.SSH_OPTS = ("-o'RSAAuthentication=no'" - + " -o 'PubkeyAuthentication=no'") -# Disabling host key checking, makes you vulnerable to MITM attacks. -# + " -o 'StrictHostKeyChecking=no'" -# + " -o 'UserKnownHostsFile /dev/null' ") - # Disabling X11 forwarding gets rid of the annoying SSH_ASKPASS from - # displaying a GUI password dialog. I have not figured out how to - # disable only SSH_ASKPASS without also disabling X11 forwarding. - # Unsetting SSH_ASKPASS on the remote side doesn't disable it! Annoying! - #self.SSH_OPTS = "-x -o'RSAAuthentication=no' -o 'PubkeyAuthentication=no'" - self.force_password = False - - self.debug_command_string = debug_command_string - - # User defined SSH options, eg, - # ssh.otions = dict(StrictHostKeyChecking="no",UserKnownHostsFile="/dev/null") - self.options = options - - def levenshtein_distance(self, a, b): - '''This calculates the Levenshtein distance between a and b. - ''' - - n, m = len(a), len(b) - if n > m: - a,b = b,a - n,m = m,n - current = range(n+1) - for i in range(1,m+1): - previous, current = current, [i]+[0]*n - for j in range(1,n+1): - add, delete = previous[j]+1, current[j-1]+1 - change = previous[j-1] - if a[j-1] != b[i-1]: - change = change + 1 - current[j] = min(add, delete, change) - return current[n] - - def try_read_prompt(self, timeout_multiplier): - '''This facilitates using communication timeouts to perform - synchronization as quickly as possible, while supporting high latency - connections with a tunable worst case performance. Fast connections - should be read almost immediately. Worst case performance for this - method is timeout_multiplier * 3 seconds. - ''' - - # maximum time allowed to read the first response - first_char_timeout = timeout_multiplier * 0.5 - - # maximum time allowed between subsequent characters - inter_char_timeout = timeout_multiplier * 0.1 - - # maximum time for reading the entire prompt - total_timeout = timeout_multiplier * 3.0 - - prompt = self.string_type() - begin = time.time() - expired = 0.0 - timeout = first_char_timeout - - while expired < total_timeout: - try: - prompt += self.read_nonblocking(size=1, timeout=timeout) - expired = time.time() - begin # updated total time expired - timeout = inter_char_timeout - except TIMEOUT: - break - - return prompt - - def sync_original_prompt (self, sync_multiplier=1.0): - '''This attempts to find the prompt. Basically, press enter and record - the response; press enter again and record the response; if the two - responses are similar then assume we are at the original prompt. - This can be a slow function. Worst case with the default sync_multiplier - can take 12 seconds. Low latency connections are more likely to fail - with a low sync_multiplier. Best case sync time gets worse with a - high sync multiplier (500 ms with default). ''' - - # All of these timing pace values are magic. - # I came up with these based on what seemed reliable for - # connecting to a heavily loaded machine I have. - self.sendline() - time.sleep(0.1) - - try: - # Clear the buffer before getting the prompt. - self.try_read_prompt(sync_multiplier) - except TIMEOUT: - pass - - self.sendline() - x = self.try_read_prompt(sync_multiplier) - - self.sendline() - a = self.try_read_prompt(sync_multiplier) - - self.sendline() - b = self.try_read_prompt(sync_multiplier) - - ld = self.levenshtein_distance(a,b) - len_a = len(a) - if len_a == 0: - return False - if float(ld)/len_a < 0.4: - return True - return False - - ### TODO: This is getting messy and I'm pretty sure this isn't perfect. - ### TODO: I need to draw a flow chart for this. - ### TODO: Unit tests for SSH tunnels, remote SSH command exec, disabling original prompt sync - def login (self, server, username, password='', terminal_type='ansi', - original_prompt=r"[#$]", login_timeout=10, port=None, - auto_prompt_reset=True, ssh_key=None, quiet=True, - sync_multiplier=1, check_local_ip=True, - password_regex=r'(?i)(?:password:)|(?:passphrase for key)', - ssh_tunnels={}, spawn_local_ssh=True, - sync_original_prompt=True, ssh_config=None): - '''This logs the user into the given server. - - It uses - 'original_prompt' to try to find the prompt right after login. When it - finds the prompt it immediately tries to reset the prompt to something - more easily matched. The default 'original_prompt' is very optimistic - and is easily fooled. It's more reliable to try to match the original - prompt as exactly as possible to prevent false matches by server - strings such as the "Message Of The Day". On many systems you can - disable the MOTD on the remote server by creating a zero-length file - called :file:`~/.hushlogin` on the remote server. If a prompt cannot be found - then this will not necessarily cause the login to fail. In the case of - a timeout when looking for the prompt we assume that the original - prompt was so weird that we could not match it, so we use a few tricks - to guess when we have reached the prompt. Then we hope for the best and - blindly try to reset the prompt to something more unique. If that fails - then login() raises an :class:`ExceptionPxssh` exception. - - In some situations it is not possible or desirable to reset the - original prompt. In this case, pass ``auto_prompt_reset=False`` to - inhibit setting the prompt to the UNIQUE_PROMPT. Remember that pxssh - uses a unique prompt in the :meth:`prompt` method. If the original prompt is - not reset then this will disable the :meth:`prompt` method unless you - manually set the :attr:`PROMPT` attribute. - - Set ``password_regex`` if there is a MOTD message with `password` in it. - Changing this is like playing in traffic, don't (p)expect it to match straight - away. - - If you require to connect to another SSH server from the your original SSH - connection set ``spawn_local_ssh`` to `False` and this will use your current - session to do so. Setting this option to `False` and not having an active session - will trigger an error. - - Set ``ssh_key`` to a file path to an SSH private key to use that SSH key - for the session authentication. - Set ``ssh_key`` to `True` to force passing the current SSH authentication socket - to the desired ``hostname``. - - Set ``ssh_config`` to a file path string of an SSH client config file to pass that - file to the client to handle itself. You may set any options you wish in here, however - doing so will require you to post extra information that you may not want to if you - run into issues. - ''' - - session_regex_array = ["(?i)are you sure you want to continue connecting", original_prompt, password_regex, "(?i)permission denied", "(?i)terminal type", TIMEOUT] - session_init_regex_array = [] - session_init_regex_array.extend(session_regex_array) - session_init_regex_array.extend(["(?i)connection closed by remote host", EOF]) - - ssh_options = ''.join([" -o '%s=%s'" % (o, v) for (o, v) in self.options.items()]) - if quiet: - ssh_options = ssh_options + ' -q' - if not check_local_ip: - ssh_options = ssh_options + " -o'NoHostAuthenticationForLocalhost=yes'" - if self.force_password: - ssh_options = ssh_options + ' ' + self.SSH_OPTS - if ssh_config is not None: - if spawn_local_ssh and not os.path.isfile(ssh_config): - raise ExceptionPxssh('SSH config does not exist or is not a file.') - ssh_options = ssh_options + '-F ' + ssh_config - if port is not None: - ssh_options = ssh_options + ' -p %s'%(str(port)) - if ssh_key is not None: - # Allow forwarding our SSH key to the current session - if ssh_key==True: - ssh_options = ssh_options + ' -A' - else: - if spawn_local_ssh and not os.path.isfile(ssh_key): - raise ExceptionPxssh('private ssh key does not exist or is not a file.') - ssh_options = ssh_options + ' -i %s' % (ssh_key) - - # SSH tunnels, make sure you know what you're putting into the lists - # under each heading. Do not expect these to open 100% of the time, - # The port you're requesting might be bound. - # - # The structure should be like this: - # { 'local': ['2424:localhost:22'], # Local SSH tunnels - # 'remote': ['2525:localhost:22'], # Remote SSH tunnels - # 'dynamic': [8888] } # Dynamic/SOCKS tunnels - if ssh_tunnels!={} and isinstance({},type(ssh_tunnels)): - tunnel_types = { - 'local':'L', - 'remote':'R', - 'dynamic':'D' - } - for tunnel_type in tunnel_types: - cmd_type = tunnel_types[tunnel_type] - if tunnel_type in ssh_tunnels: - tunnels = ssh_tunnels[tunnel_type] - for tunnel in tunnels: - if spawn_local_ssh==False: - tunnel = quote(str(tunnel)) - ssh_options = ssh_options + ' -' + cmd_type + ' ' + str(tunnel) - cmd = "ssh %s -l %s %s" % (ssh_options, username, server) - if self.debug_command_string: - return(cmd) - - # Are we asking for a local ssh command or to spawn one in another session? - if spawn_local_ssh: - spawn._spawn(self, cmd) - else: - self.sendline(cmd) - - # This does not distinguish between a remote server 'password' prompt - # and a local ssh 'passphrase' prompt (for unlocking a private key). - i = self.expect(session_init_regex_array, timeout=login_timeout) - - # First phase - if i==0: - # New certificate -- always accept it. - # This is what you get if SSH does not have the remote host's - # public key stored in the 'known_hosts' cache. - self.sendline("yes") - i = self.expect(session_regex_array) - if i==2: # password or passphrase - self.sendline(password) - i = self.expect(session_regex_array) - if i==4: - self.sendline(terminal_type) - i = self.expect(session_regex_array) - if i==7: - self.close() - raise ExceptionPxssh('Could not establish connection to host') - - # Second phase - if i==0: - # This is weird. This should not happen twice in a row. - self.close() - raise ExceptionPxssh('Weird error. Got "are you sure" prompt twice.') - elif i==1: # can occur if you have a public key pair set to authenticate. - ### TODO: May NOT be OK if expect() got tricked and matched a false prompt. - pass - elif i==2: # password prompt again - # For incorrect passwords, some ssh servers will - # ask for the password again, others return 'denied' right away. - # If we get the password prompt again then this means - # we didn't get the password right the first time. - self.close() - raise ExceptionPxssh('password refused') - elif i==3: # permission denied -- password was bad. - self.close() - raise ExceptionPxssh('permission denied') - elif i==4: # terminal type again? WTF? - self.close() - raise ExceptionPxssh('Weird error. Got "terminal type" prompt twice.') - elif i==5: # Timeout - #This is tricky... I presume that we are at the command-line prompt. - #It may be that the shell prompt was so weird that we couldn't match - #it. Or it may be that we couldn't log in for some other reason. I - #can't be sure, but it's safe to guess that we did login because if - #I presume wrong and we are not logged in then this should be caught - #later when I try to set the shell prompt. - pass - elif i==6: # Connection closed by remote host - self.close() - raise ExceptionPxssh('connection closed') - else: # Unexpected - self.close() - raise ExceptionPxssh('unexpected login response') - if sync_original_prompt: - if not self.sync_original_prompt(sync_multiplier): - self.close() - raise ExceptionPxssh('could not synchronize with original prompt') - # We appear to be in. - # set shell prompt to something unique. - if auto_prompt_reset: - if not self.set_unique_prompt(): - self.close() - raise ExceptionPxssh('could not set shell prompt ' - '(received: %r, expected: %r).' % ( - self.before, self.PROMPT,)) - return True - - def logout (self): - '''Sends exit to the remote shell. - - If there are stopped jobs then this automatically sends exit twice. - ''' - self.sendline("exit") - index = self.expect([EOF, "(?i)there are stopped jobs"]) - if index==1: - self.sendline("exit") - self.expect(EOF) - self.close() - - def prompt(self, timeout=-1): - '''Match the next shell prompt. - - This is little more than a short-cut to the :meth:`~pexpect.spawn.expect` - method. Note that if you called :meth:`login` with - ``auto_prompt_reset=False``, then before calling :meth:`prompt` you must - set the :attr:`PROMPT` attribute to a regex that it will use for - matching the prompt. - - Calling :meth:`prompt` will erase the contents of the :attr:`before` - attribute even if no prompt is ever matched. If timeout is not given or - it is set to -1 then self.timeout is used. - - :return: True if the shell prompt was matched, False if the timeout was - reached. - ''' - - if timeout == -1: - timeout = self.timeout - i = self.expect([self.PROMPT, TIMEOUT], timeout=timeout) - if i==1: - return False - return True - - def set_unique_prompt(self): - '''This sets the remote prompt to something more unique than ``#`` or ``$``. - This makes it easier for the :meth:`prompt` method to match the shell prompt - unambiguously. This method is called automatically by the :meth:`login` - method, but you may want to call it manually if you somehow reset the - shell prompt. For example, if you 'su' to a different user then you - will need to manually reset the prompt. This sends shell commands to - the remote host to set the prompt, so this assumes the remote host is - ready to receive commands. - - Alternatively, you may use your own prompt pattern. In this case you - should call :meth:`login` with ``auto_prompt_reset=False``; then set the - :attr:`PROMPT` attribute to a regular expression. After that, the - :meth:`prompt` method will try to match your prompt pattern. - ''' - - self.sendline("unset PROMPT_COMMAND") - self.sendline(self.PROMPT_SET_SH) # sh-style - i = self.expect ([TIMEOUT, self.PROMPT], timeout=10) - if i == 0: # csh-style - self.sendline(self.PROMPT_SET_CSH) - i = self.expect([TIMEOUT, self.PROMPT], timeout=10) - if i == 0: - return False - return True - -# vi:ts=4:sw=4:expandtab:ft=python: diff --git a/lldb/third_party/Python/module/pexpect-4.6/pexpect/replwrap.py b/lldb/third_party/Python/module/pexpect-4.6/pexpect/replwrap.py deleted file mode 100644 index ed0e657d739c..000000000000 --- a/lldb/third_party/Python/module/pexpect-4.6/pexpect/replwrap.py +++ /dev/null @@ -1,122 +0,0 @@ -"""Generic wrapper for read-eval-print-loops, a.k.a. interactive shells -""" -import os.path -import signal -import sys - -import pexpect - -PY3 = (sys.version_info[0] >= 3) - -if PY3: - basestring = str - -PEXPECT_PROMPT = u'[PEXPECT_PROMPT>' -PEXPECT_CONTINUATION_PROMPT = u'[PEXPECT_PROMPT+' - -class REPLWrapper(object): - """Wrapper for a REPL. - - :param cmd_or_spawn: This can either be an instance of :class:`pexpect.spawn` - in which a REPL has already been started, or a str command to start a new - REPL process. - :param str orig_prompt: The prompt to expect at first. - :param str prompt_change: A command to change the prompt to something more - unique. If this is ``None``, the prompt will not be changed. This will - be formatted with the new and continuation prompts as positional - parameters, so you can use ``{}`` style formatting to insert them into - the command. - :param str new_prompt: The more unique prompt to expect after the change. - :param str extra_init_cmd: Commands to do extra initialisation, such as - disabling pagers. - """ - def __init__(self, cmd_or_spawn, orig_prompt, prompt_change, - new_prompt=PEXPECT_PROMPT, - continuation_prompt=PEXPECT_CONTINUATION_PROMPT, - extra_init_cmd=None): - if isinstance(cmd_or_spawn, basestring): - self.child = pexpect.spawn(cmd_or_spawn, echo=False, encoding='utf-8') - else: - self.child = cmd_or_spawn - if self.child.echo: - # Existing spawn instance has echo enabled, disable it - # to prevent our input from being repeated to output. - self.child.setecho(False) - self.child.waitnoecho() - - if prompt_change is None: - self.prompt = orig_prompt - else: - self.set_prompt(orig_prompt, - prompt_change.format(new_prompt, continuation_prompt)) - self.prompt = new_prompt - self.continuation_prompt = continuation_prompt - - self._expect_prompt() - - if extra_init_cmd is not None: - self.run_command(extra_init_cmd) - - def set_prompt(self, orig_prompt, prompt_change): - self.child.expect(orig_prompt) - self.child.sendline(prompt_change) - - def _expect_prompt(self, timeout=-1): - return self.child.expect_exact([self.prompt, self.continuation_prompt], - timeout=timeout) - - def run_command(self, command, timeout=-1): - """Send a command to the REPL, wait for and return output. - - :param str command: The command to send. Trailing newlines are not needed. - This should be a complete block of input that will trigger execution; - if a continuation prompt is found after sending input, :exc:`ValueError` - will be raised. - :param int timeout: How long to wait for the next prompt. -1 means the - default from the :class:`pexpect.spawn` object (default 30 seconds). - None means to wait indefinitely. - """ - # Split up multiline commands and feed them in bit-by-bit - cmdlines = command.splitlines() - # splitlines ignores trailing newlines - add it back in manually - if command.endswith('\n'): - cmdlines.append('') - if not cmdlines: - raise ValueError("No command was given") - - res = [] - self.child.sendline(cmdlines[0]) - for line in cmdlines[1:]: - self._expect_prompt(timeout=timeout) - res.append(self.child.before) - self.child.sendline(line) - - # Command was fully submitted, now wait for the next prompt - if self._expect_prompt(timeout=timeout) == 1: - # We got the continuation prompt - command was incomplete - self.child.kill(signal.SIGINT) - self._expect_prompt(timeout=1) - raise ValueError("Continuation prompt found - input was incomplete:\n" - + command) - return u''.join(res + [self.child.before]) - -def python(command="python"): - """Start a Python shell and return a :class:`REPLWrapper` object.""" - return REPLWrapper(command, u">>> ", u"import sys; sys.ps1={0!r}; sys.ps2={1!r}") - -def bash(command="bash"): - """Start a bash shell and return a :class:`REPLWrapper` object.""" - bashrc = os.path.join(os.path.dirname(__file__), 'bashrc.sh') - child = pexpect.spawn(command, ['--rcfile', bashrc], echo=False, - encoding='utf-8') - - # If the user runs 'env', the value of PS1 will be in the output. To avoid - # replwrap seeing that as the next prompt, we'll embed the marker characters - # for invisible characters in the prompt; these show up when inspecting the - # environment variable, but not when bash displays the prompt. - ps1 = PEXPECT_PROMPT[:5] + u'\\[\\]' + PEXPECT_PROMPT[5:] - ps2 = PEXPECT_CONTINUATION_PROMPT[:5] + u'\\[\\]' + PEXPECT_CONTINUATION_PROMPT[5:] - prompt_change = u"PS1='{0}' PS2='{1}' PROMPT_COMMAND=''".format(ps1, ps2) - - return REPLWrapper(child, u'\\$', prompt_change, - extra_init_cmd="export PAGER=cat") diff --git a/lldb/third_party/Python/module/pexpect-4.6/pexpect/run.py b/lldb/third_party/Python/module/pexpect-4.6/pexpect/run.py deleted file mode 100644 index d9dfe76ba585..000000000000 --- a/lldb/third_party/Python/module/pexpect-4.6/pexpect/run.py +++ /dev/null @@ -1,157 +0,0 @@ -import sys -import types - -from .exceptions import EOF, TIMEOUT -from .pty_spawn import spawn - -def run(command, timeout=30, withexitstatus=False, events=None, - extra_args=None, logfile=None, cwd=None, env=None, **kwargs): - - ''' - This function runs the given command; waits for it to finish; then - returns all output as a string. STDERR is included in output. If the full - path to the command is not given then the path is searched. - - Note that lines are terminated by CR/LF (\\r\\n) combination even on - UNIX-like systems because this is the standard for pseudottys. If you set - 'withexitstatus' to true, then run will return a tuple of (command_output, - exitstatus). If 'withexitstatus' is false then this returns just - command_output. - - The run() function can often be used instead of creating a spawn instance. - For example, the following code uses spawn:: - - from pexpect import * - child = spawn('scp foo user@example.com:.') - child.expect('(?i)password') - child.sendline(mypassword) - - The previous code can be replace with the following:: - - from pexpect import * - run('scp foo user@example.com:.', events={'(?i)password': mypassword}) - - **Examples** - - Start the apache daemon on the local machine:: - - from pexpect import * - run("/usr/local/apache/bin/apachectl start") - - Check in a file using SVN:: - - from pexpect import * - run("svn ci -m 'automatic commit' my_file.py") - - Run a command and capture exit status:: - - from pexpect import * - (command_output, exitstatus) = run('ls -l /bin', withexitstatus=1) - - The following will run SSH and execute 'ls -l' on the remote machine. The - password 'secret' will be sent if the '(?i)password' pattern is ever seen:: - - run("ssh username@machine.example.com 'ls -l'", - events={'(?i)password':'secret\\n'}) - - This will start mencoder to rip a video from DVD. This will also display - progress ticks every 5 seconds as it runs. For example:: - - from pexpect import * - def print_ticks(d): - print d['event_count'], - run("mencoder dvd://1 -o video.avi -oac copy -ovc copy", - events={TIMEOUT:print_ticks}, timeout=5) - - The 'events' argument should be either a dictionary or a tuple list that - contains patterns and responses. Whenever one of the patterns is seen - in the command output, run() will send the associated response string. - So, run() in the above example can be also written as: - - run("mencoder dvd://1 -o video.avi -oac copy -ovc copy", - events=[(TIMEOUT,print_ticks)], timeout=5) - - Use a tuple list for events if the command output requires a delicate - control over what pattern should be matched, since the tuple list is passed - to pexpect() as its pattern list, with the order of patterns preserved. - - Note that you should put newlines in your string if Enter is necessary. - - Like the example above, the responses may also contain a callback, either - a function or method. It should accept a dictionary value as an argument. - The dictionary contains all the locals from the run() function, so you can - access the child spawn object or any other variable defined in run() - (event_count, child, and extra_args are the most useful). A callback may - return True to stop the current run process. Otherwise run() continues - until the next event. A callback may also return a string which will be - sent to the child. 'extra_args' is not used by directly run(). It provides - a way to pass data to a callback function through run() through the locals - dictionary passed to a callback. - - Like :class:`spawn`, passing *encoding* will make it work with unicode - instead of bytes. You can pass *codec_errors* to control how errors in - encoding and decoding are handled. - ''' - if timeout == -1: - child = spawn(command, maxread=2000, logfile=logfile, cwd=cwd, env=env, - **kwargs) - else: - child = spawn(command, timeout=timeout, maxread=2000, logfile=logfile, - cwd=cwd, env=env, **kwargs) - if isinstance(events, list): - patterns= [x for x,y in events] - responses = [y for x,y in events] - elif isinstance(events, dict): - patterns = list(events.keys()) - responses = list(events.values()) - else: - # This assumes EOF or TIMEOUT will eventually cause run to terminate. - patterns = None - responses = None - child_result_list = [] - event_count = 0 - while True: - try: - index = child.expect(patterns) - if isinstance(child.after, child.allowed_string_types): - child_result_list.append(child.before + child.after) - else: - # child.after may have been a TIMEOUT or EOF, - # which we don't want appended to the list. - child_result_list.append(child.before) - if isinstance(responses[index], child.allowed_string_types): - child.send(responses[index]) - elif (isinstance(responses[index], types.FunctionType) or - isinstance(responses[index], types.MethodType)): - callback_result = responses[index](locals()) - sys.stdout.flush() - if isinstance(callback_result, child.allowed_string_types): - child.send(callback_result) - elif callback_result: - break - else: - raise TypeError("parameter `event' at index {index} must be " - "a string, method, or function: {value!r}" - .format(index=index, value=responses[index])) - event_count = event_count + 1 - except TIMEOUT: - child_result_list.append(child.before) - break - except EOF: - child_result_list.append(child.before) - break - child_result = child.string_type().join(child_result_list) - if withexitstatus: - child.close() - return (child_result, child.exitstatus) - else: - return child_result - -def runu(command, timeout=30, withexitstatus=False, events=None, - extra_args=None, logfile=None, cwd=None, env=None, **kwargs): - """Deprecated: pass encoding to run() instead. - """ - kwargs.setdefault('encoding', 'utf-8') - return run(command, timeout=timeout, withexitstatus=withexitstatus, - events=events, extra_args=extra_args, logfile=logfile, cwd=cwd, - env=env, **kwargs) diff --git a/lldb/third_party/Python/module/pexpect-4.6/pexpect/screen.py b/lldb/third_party/Python/module/pexpect-4.6/pexpect/screen.py deleted file mode 100644 index 5ab45b946795..000000000000 --- a/lldb/third_party/Python/module/pexpect-4.6/pexpect/screen.py +++ /dev/null @@ -1,431 +0,0 @@ -'''This implements a virtual screen. This is used to support ANSI terminal -emulation. The screen representation and state is implemented in this class. -Most of the methods are inspired by ANSI screen control codes. The -:class:`~pexpect.ANSI.ANSI` class extends this class to add parsing of ANSI -escape codes. - -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' - -import codecs -import copy -import sys - -import warnings - -warnings.warn(("pexpect.screen and pexpect.ANSI are deprecated. " - "We recommend using pyte to emulate a terminal screen: " - "https://pypi.python.org/pypi/pyte"), - stacklevel=2) - -NUL = 0 # Fill character; ignored on input. -ENQ = 5 # Transmit answerback message. -BEL = 7 # Ring the bell. -BS = 8 # Move cursor left. -HT = 9 # Move cursor to next tab stop. -LF = 10 # Line feed. -VT = 11 # Same as LF. -FF = 12 # Same as LF. -CR = 13 # Move cursor to left margin or newline. -SO = 14 # Invoke G1 character set. -SI = 15 # Invoke G0 character set. -XON = 17 # Resume transmission. -XOFF = 19 # Halt transmission. -CAN = 24 # Cancel escape sequence. -SUB = 26 # Same as CAN. -ESC = 27 # Introduce a control sequence. -DEL = 127 # Fill character; ignored on input. -SPACE = u' ' # Space or blank character. - -PY3 = (sys.version_info[0] >= 3) -if PY3: - unicode = str - -def constrain (n, min, max): - - '''This returns a number, n constrained to the min and max bounds. ''' - - if n < min: - return min - if n > max: - return max - return n - -class screen: - '''This object maintains the state of a virtual text screen as a - rectangular array. This maintains a virtual cursor position and handles - scrolling as characters are added. This supports most of the methods needed - by an ANSI text screen. Row and column indexes are 1-based (not zero-based, - like arrays). - - Characters are represented internally using unicode. Methods that accept - input characters, when passed 'bytes' (which in Python 2 is equivalent to - 'str'), convert them from the encoding specified in the 'encoding' - parameter to the constructor. Methods that return screen contents return - unicode strings, with the exception of __str__() under Python 2. Passing - ``encoding=None`` limits the API to only accept unicode input, so passing - bytes in will raise :exc:`TypeError`. - ''' - def __init__(self, r=24, c=80, encoding='latin-1', encoding_errors='replace'): - '''This initializes a blank screen of the given dimensions.''' - - self.rows = r - self.cols = c - self.encoding = encoding - self.encoding_errors = encoding_errors - if encoding is not None: - self.decoder = codecs.getincrementaldecoder(encoding)(encoding_errors) - else: - self.decoder = None - self.cur_r = 1 - self.cur_c = 1 - self.cur_saved_r = 1 - self.cur_saved_c = 1 - self.scroll_row_start = 1 - self.scroll_row_end = self.rows - self.w = [ [SPACE] * self.cols for _ in range(self.rows)] - - def _decode(self, s): - '''This converts from the external coding system (as passed to - the constructor) to the internal one (unicode). ''' - if self.decoder is not None: - return self.decoder.decode(s) - else: - raise TypeError("This screen was constructed with encoding=None, " - "so it does not handle bytes.") - - def _unicode(self): - '''This returns a printable representation of the screen as a unicode - string (which, under Python 3.x, is the same as 'str'). The end of each - screen line is terminated by a newline.''' - - return u'\n'.join ([ u''.join(c) for c in self.w ]) - - if PY3: - __str__ = _unicode - else: - __unicode__ = _unicode - - def __str__(self): - '''This returns a printable representation of the screen. The end of - each screen line is terminated by a newline. ''' - encoding = self.encoding or 'ascii' - return self._unicode().encode(encoding, 'replace') - - def dump (self): - '''This returns a copy of the screen as a unicode string. This is similar to - __str__/__unicode__ except that lines are not terminated with line - feeds.''' - - return u''.join ([ u''.join(c) for c in self.w ]) - - def pretty (self): - '''This returns a copy of the screen as a unicode string with an ASCII - text box around the screen border. This is similar to - __str__/__unicode__ except that it adds a box.''' - - top_bot = u'+' + u'-'*self.cols + u'+\n' - return top_bot + u'\n'.join([u'|'+line+u'|' for line in unicode(self).split(u'\n')]) + u'\n' + top_bot - - def fill (self, ch=SPACE): - - if isinstance(ch, bytes): - ch = self._decode(ch) - - self.fill_region (1,1,self.rows,self.cols, ch) - - def fill_region (self, rs,cs, re,ce, ch=SPACE): - - if isinstance(ch, bytes): - ch = self._decode(ch) - - rs = constrain (rs, 1, self.rows) - re = constrain (re, 1, self.rows) - cs = constrain (cs, 1, self.cols) - ce = constrain (ce, 1, self.cols) - if rs > re: - rs, re = re, rs - if cs > ce: - cs, ce = ce, cs - for r in range (rs, re+1): - for c in range (cs, ce + 1): - self.put_abs (r,c,ch) - - def cr (self): - '''This moves the cursor to the beginning (col 1) of the current row. - ''' - - self.cursor_home (self.cur_r, 1) - - def lf (self): - '''This moves the cursor down with scrolling. - ''' - - old_r = self.cur_r - self.cursor_down() - if old_r == self.cur_r: - self.scroll_up () - self.erase_line() - - def crlf (self): - '''This advances the cursor with CRLF properties. - The cursor will line wrap and the screen may scroll. - ''' - - self.cr () - self.lf () - - def newline (self): - '''This is an alias for crlf(). - ''' - - self.crlf() - - def put_abs (self, r, c, ch): - '''Screen array starts at 1 index.''' - - r = constrain (r, 1, self.rows) - c = constrain (c, 1, self.cols) - if isinstance(ch, bytes): - ch = self._decode(ch)[0] - else: - ch = ch[0] - self.w[r-1][c-1] = ch - - def put (self, ch): - '''This puts a characters at the current cursor position. - ''' - - if isinstance(ch, bytes): - ch = self._decode(ch) - - self.put_abs (self.cur_r, self.cur_c, ch) - - def insert_abs (self, r, c, ch): - '''This inserts a character at (r,c). Everything under - and to the right is shifted right one character. - The last character of the line is lost. - ''' - - if isinstance(ch, bytes): - ch = self._decode(ch) - - r = constrain (r, 1, self.rows) - c = constrain (c, 1, self.cols) - for ci in range (self.cols, c, -1): - self.put_abs (r,ci, self.get_abs(r,ci-1)) - self.put_abs (r,c,ch) - - def insert (self, ch): - - if isinstance(ch, bytes): - ch = self._decode(ch) - - self.insert_abs (self.cur_r, self.cur_c, ch) - - def get_abs (self, r, c): - - r = constrain (r, 1, self.rows) - c = constrain (c, 1, self.cols) - return self.w[r-1][c-1] - - def get (self): - - self.get_abs (self.cur_r, self.cur_c) - - def get_region (self, rs,cs, re,ce): - '''This returns a list of lines representing the region. - ''' - - rs = constrain (rs, 1, self.rows) - re = constrain (re, 1, self.rows) - cs = constrain (cs, 1, self.cols) - ce = constrain (ce, 1, self.cols) - if rs > re: - rs, re = re, rs - if cs > ce: - cs, ce = ce, cs - sc = [] - for r in range (rs, re+1): - line = u'' - for c in range (cs, ce + 1): - ch = self.get_abs (r,c) - line = line + ch - sc.append (line) - return sc - - def cursor_constrain (self): - '''This keeps the cursor within the screen area. - ''' - - self.cur_r = constrain (self.cur_r, 1, self.rows) - self.cur_c = constrain (self.cur_c, 1, self.cols) - - def cursor_home (self, r=1, c=1): # [{ROW};{COLUMN}H - - self.cur_r = r - self.cur_c = c - self.cursor_constrain () - - def cursor_back (self,count=1): # [{COUNT}D (not confused with down) - - self.cur_c = self.cur_c - count - self.cursor_constrain () - - def cursor_down (self,count=1): # [{COUNT}B (not confused with back) - - self.cur_r = self.cur_r + count - self.cursor_constrain () - - def cursor_forward (self,count=1): # [{COUNT}C - - self.cur_c = self.cur_c + count - self.cursor_constrain () - - def cursor_up (self,count=1): # [{COUNT}A - - self.cur_r = self.cur_r - count - self.cursor_constrain () - - def cursor_up_reverse (self): # M (called RI -- Reverse Index) - - old_r = self.cur_r - self.cursor_up() - if old_r == self.cur_r: - self.scroll_up() - - def cursor_force_position (self, r, c): # [{ROW};{COLUMN}f - '''Identical to Cursor Home.''' - - self.cursor_home (r, c) - - def cursor_save (self): # [s - '''Save current cursor position.''' - - self.cursor_save_attrs() - - def cursor_unsave (self): # [u - '''Restores cursor position after a Save Cursor.''' - - self.cursor_restore_attrs() - - def cursor_save_attrs (self): # 7 - '''Save current cursor position.''' - - self.cur_saved_r = self.cur_r - self.cur_saved_c = self.cur_c - - def cursor_restore_attrs (self): # 8 - '''Restores cursor position after a Save Cursor.''' - - self.cursor_home (self.cur_saved_r, self.cur_saved_c) - - def scroll_constrain (self): - '''This keeps the scroll region within the screen region.''' - - if self.scroll_row_start <= 0: - self.scroll_row_start = 1 - if self.scroll_row_end > self.rows: - self.scroll_row_end = self.rows - - def scroll_screen (self): # [r - '''Enable scrolling for entire display.''' - - self.scroll_row_start = 1 - self.scroll_row_end = self.rows - - def scroll_screen_rows (self, rs, re): # [{start};{end}r - '''Enable scrolling from row {start} to row {end}.''' - - self.scroll_row_start = rs - self.scroll_row_end = re - self.scroll_constrain() - - def scroll_down (self): # D - '''Scroll display down one line.''' - - # Screen is indexed from 1, but arrays are indexed from 0. - s = self.scroll_row_start - 1 - e = self.scroll_row_end - 1 - self.w[s+1:e+1] = copy.deepcopy(self.w[s:e]) - - def scroll_up (self): # M - '''Scroll display up one line.''' - - # Screen is indexed from 1, but arrays are indexed from 0. - s = self.scroll_row_start - 1 - e = self.scroll_row_end - 1 - self.w[s:e] = copy.deepcopy(self.w[s+1:e+1]) - - def erase_end_of_line (self): # [0K -or- [K - '''Erases from the current cursor position to the end of the current - line.''' - - self.fill_region (self.cur_r, self.cur_c, self.cur_r, self.cols) - - def erase_start_of_line (self): # [1K - '''Erases from the current cursor position to the start of the current - line.''' - - self.fill_region (self.cur_r, 1, self.cur_r, self.cur_c) - - def erase_line (self): # [2K - '''Erases the entire current line.''' - - self.fill_region (self.cur_r, 1, self.cur_r, self.cols) - - def erase_down (self): # [0J -or- [J - '''Erases the screen from the current line down to the bottom of the - screen.''' - - self.erase_end_of_line () - self.fill_region (self.cur_r + 1, 1, self.rows, self.cols) - - def erase_up (self): # [1J - '''Erases the screen from the current line up to the top of the - screen.''' - - self.erase_start_of_line () - self.fill_region (self.cur_r-1, 1, 1, self.cols) - - def erase_screen (self): # [2J - '''Erases the screen with the background color.''' - - self.fill () - - def set_tab (self): # H - '''Sets a tab at the current position.''' - - pass - - def clear_tab (self): # [g - '''Clears tab at the current position.''' - - pass - - def clear_all_tabs (self): # [3g - '''Clears all tabs.''' - - pass - -# Insert line Esc [ Pn L -# Delete line Esc [ Pn M -# Delete character Esc [ Pn P -# Scrolling region Esc [ Pn(top);Pn(bot) r - diff --git a/lldb/third_party/Python/module/pexpect-4.6/pexpect/spawnbase.py b/lldb/third_party/Python/module/pexpect-4.6/pexpect/spawnbase.py deleted file mode 100644 index 589d5ec92465..000000000000 --- a/lldb/third_party/Python/module/pexpect-4.6/pexpect/spawnbase.py +++ /dev/null @@ -1,522 +0,0 @@ -from io import StringIO, BytesIO -import codecs -import os -import sys -import re -import errno -from .exceptions import ExceptionPexpect, EOF, TIMEOUT -from .expect import Expecter, searcher_string, searcher_re - -PY3 = (sys.version_info[0] >= 3) -text_type = str if PY3 else unicode - -class _NullCoder(object): - """Pass bytes through unchanged.""" - @staticmethod - def encode(b, final=False): - return b - - @staticmethod - def decode(b, final=False): - return b - -class SpawnBase(object): - """A base class providing the backwards-compatible spawn API for Pexpect. - - This should not be instantiated directly: use :class:`pexpect.spawn` or - :class:`pexpect.fdpexpect.fdspawn`. - """ - encoding = None - pid = None - flag_eof = False - - def __init__(self, timeout=60, maxread=2000, searchwindowsize=None, - logfile=None, encoding=None, codec_errors='strict'): - self.stdin = sys.stdin - self.stdout = sys.stdout - self.stderr = sys.stderr - - self.searcher = None - self.ignorecase = False - self.before = None - self.after = None - self.match = None - self.match_index = None - self.terminated = True - self.exitstatus = None - self.signalstatus = None - # status returned by os.waitpid - self.status = None - # the child file descriptor is initially closed - self.child_fd = -1 - self.timeout = timeout - self.delimiter = EOF - self.logfile = logfile - # input from child (read_nonblocking) - self.logfile_read = None - # output to send (send, sendline) - self.logfile_send = None - # max bytes to read at one time into buffer - self.maxread = maxread - # Data before searchwindowsize point is preserved, but not searched. - self.searchwindowsize = searchwindowsize - # Delay used before sending data to child. Time in seconds. - # Set this to None to skip the time.sleep() call completely. - self.delaybeforesend = 0.05 - # Used by close() to give kernel time to update process status. - # Time in seconds. - self.delayafterclose = 0.1 - # Used by terminate() to give kernel time to update process status. - # Time in seconds. - self.delayafterterminate = 0.1 - # Delay in seconds to sleep after each call to read_nonblocking(). - # Set this to None to skip the time.sleep() call completely: that - # would restore the behavior from pexpect-2.0 (for performance - # reasons or because you don't want to release Python's global - # interpreter lock). - self.delayafterread = 0.0001 - self.softspace = False - self.name = '<' + repr(self) + '>' - self.closed = True - - # Unicode interface - self.encoding = encoding - self.codec_errors = codec_errors - if encoding is None: - # bytes mode (accepts some unicode for backwards compatibility) - self._encoder = self._decoder = _NullCoder() - self.string_type = bytes - self.buffer_type = BytesIO - self.crlf = b'\r\n' - if PY3: - self.allowed_string_types = (bytes, str) - self.linesep = os.linesep.encode('ascii') - def write_to_stdout(b): - try: - return sys.stdout.buffer.write(b) - except AttributeError: - # If stdout has been replaced, it may not have .buffer - return sys.stdout.write(b.decode('ascii', 'replace')) - self.write_to_stdout = write_to_stdout - else: - self.allowed_string_types = (basestring,) # analysis:ignore - self.linesep = os.linesep - self.write_to_stdout = sys.stdout.write - else: - # unicode mode - self._encoder = codecs.getincrementalencoder(encoding)(codec_errors) - self._decoder = codecs.getincrementaldecoder(encoding)(codec_errors) - self.string_type = text_type - self.buffer_type = StringIO - self.crlf = u'\r\n' - self.allowed_string_types = (text_type, ) - if PY3: - self.linesep = os.linesep - else: - self.linesep = os.linesep.decode('ascii') - # This can handle unicode in both Python 2 and 3 - self.write_to_stdout = sys.stdout.write - # storage for async transport - self.async_pw_transport = None - # This is the read buffer. See maxread. - self._buffer = self.buffer_type() - - def _log(self, s, direction): - if self.logfile is not None: - self.logfile.write(s) - self.logfile.flush() - second_log = self.logfile_send if (direction=='send') else self.logfile_read - if second_log is not None: - second_log.write(s) - second_log.flush() - - # For backwards compatibility, in bytes mode (when encoding is None) - # unicode is accepted for send and expect. Unicode mode is strictly unicode - # only. - def _coerce_expect_string(self, s): - if self.encoding is None and not isinstance(s, bytes): - return s.encode('ascii') - return s - - def _coerce_send_string(self, s): - if self.encoding is None and not isinstance(s, bytes): - return s.encode('utf-8') - return s - - def _get_buffer(self): - return self._buffer.getvalue() - - def _set_buffer(self, value): - self._buffer = self.buffer_type() - self._buffer.write(value) - - # This property is provided for backwards compatibility (self.buffer used - # to be a string/bytes object) - buffer = property(_get_buffer, _set_buffer) - - def read_nonblocking(self, size=1, timeout=None): - """This reads data from the file descriptor. - - This is a simple implementation suitable for a regular file. Subclasses using ptys or pipes should override it. - - The timeout parameter is ignored. - """ - - try: - s = os.read(self.child_fd, size) - except OSError as err: - if err.args[0] == errno.EIO: - # Linux-style EOF - self.flag_eof = True - raise EOF('End Of File (EOF). Exception style platform.') - raise - if s == b'': - # BSD-style EOF - self.flag_eof = True - raise EOF('End Of File (EOF). Empty string style platform.') - - s = self._decoder.decode(s, final=False) - self._log(s, 'read') - return s - - def _pattern_type_err(self, pattern): - raise TypeError('got {badtype} ({badobj!r}) as pattern, must be one' - ' of: {goodtypes}, pexpect.EOF, pexpect.TIMEOUT'\ - .format(badtype=type(pattern), - badobj=pattern, - goodtypes=', '.join([str(ast)\ - for ast in self.allowed_string_types]) - ) - ) - - def compile_pattern_list(self, patterns): - '''This compiles a pattern-string or a list of pattern-strings. - Patterns must be a StringType, EOF, TIMEOUT, SRE_Pattern, or a list of - those. Patterns may also be None which results in an empty list (you - might do this if waiting for an EOF or TIMEOUT condition without - expecting any pattern). - - This is used by expect() when calling expect_list(). Thus expect() is - nothing more than:: - - cpl = self.compile_pattern_list(pl) - return self.expect_list(cpl, timeout) - - If you are using expect() within a loop it may be more - efficient to compile the patterns first and then call expect_list(). - This avoid calls in a loop to compile_pattern_list():: - - cpl = self.compile_pattern_list(my_pattern) - while some_condition: - ... - i = self.expect_list(cpl, timeout) - ... - ''' - - if patterns is None: - return [] - if not isinstance(patterns, list): - patterns = [patterns] - - # Allow dot to match \n - compile_flags = re.DOTALL - if self.ignorecase: - compile_flags = compile_flags | re.IGNORECASE - compiled_pattern_list = [] - for idx, p in enumerate(patterns): - if isinstance(p, self.allowed_string_types): - p = self._coerce_expect_string(p) - compiled_pattern_list.append(re.compile(p, compile_flags)) - elif p is EOF: - compiled_pattern_list.append(EOF) - elif p is TIMEOUT: - compiled_pattern_list.append(TIMEOUT) - elif isinstance(p, type(re.compile(''))): - compiled_pattern_list.append(p) - else: - self._pattern_type_err(p) - return compiled_pattern_list - - def expect(self, pattern, timeout=-1, searchwindowsize=-1, async_=False, **kw): - '''This seeks through the stream until a pattern is matched. The - pattern is overloaded and may take several types. The pattern can be a - StringType, EOF, a compiled re, or a list of any of those types. - Strings will be compiled to re types. This returns the index into the - pattern list. If the pattern was not a list this returns index 0 on a - successful match. This may raise exceptions for EOF or TIMEOUT. To - avoid the EOF or TIMEOUT exceptions add EOF or TIMEOUT to the pattern - list. That will cause expect to match an EOF or TIMEOUT condition - instead of raising an exception. - - If you pass a list of patterns and more than one matches, the first - match in the stream is chosen. If more than one pattern matches at that - point, the leftmost in the pattern list is chosen. For example:: - - # the input is 'foobar' - index = p.expect(['bar', 'foo', 'foobar']) - # returns 1('foo') even though 'foobar' is a "better" match - - Please note, however, that buffering can affect this behavior, since - input arrives in unpredictable chunks. For example:: - - # the input is 'foobar' - index = p.expect(['foobar', 'foo']) - # returns 0('foobar') if all input is available at once, - # but returns 1('foo') if parts of the final 'bar' arrive late - - When a match is found for the given pattern, the class instance - attribute *match* becomes an re.MatchObject result. Should an EOF - or TIMEOUT pattern match, then the match attribute will be an instance - of that exception class. The pairing before and after class - instance attributes are views of the data preceding and following - the matching pattern. On general exception, class attribute - *before* is all data received up to the exception, while *match* and - *after* attributes are value None. - - When the keyword argument timeout is -1 (default), then TIMEOUT will - raise after the default value specified by the class timeout - attribute. When None, TIMEOUT will not be raised and may block - indefinitely until match. - - When the keyword argument searchwindowsize is -1 (default), then the - value specified by the class maxread attribute is used. - - A list entry may be EOF or TIMEOUT instead of a string. This will - catch these exceptions and return the index of the list entry instead - of raising the exception. The attribute 'after' will be set to the - exception type. The attribute 'match' will be None. This allows you to - write code like this:: - - index = p.expect(['good', 'bad', pexpect.EOF, pexpect.TIMEOUT]) - if index == 0: - do_something() - elif index == 1: - do_something_else() - elif index == 2: - do_some_other_thing() - elif index == 3: - do_something_completely_different() - - instead of code like this:: - - try: - index = p.expect(['good', 'bad']) - if index == 0: - do_something() - elif index == 1: - do_something_else() - except EOF: - do_some_other_thing() - except TIMEOUT: - do_something_completely_different() - - These two forms are equivalent. It all depends on what you want. You - can also just expect the EOF if you are waiting for all output of a - child to finish. For example:: - - p = pexpect.spawn('/bin/ls') - p.expect(pexpect.EOF) - print p.before - - If you are trying to optimize for speed then see expect_list(). - - On Python 3.4, or Python 3.3 with asyncio installed, passing - ``async_=True`` will make this return an :mod:`asyncio` coroutine, - which you can yield from to get the same result that this method would - normally give directly. So, inside a coroutine, you can replace this code:: - - index = p.expect(patterns) - - With this non-blocking form:: - - index = yield from p.expect(patterns, async_=True) - ''' - if 'async' in kw: - async_ = kw.pop('async') - if kw: - raise TypeError("Unknown keyword arguments: {}".format(kw)) - - compiled_pattern_list = self.compile_pattern_list(pattern) - return self.expect_list(compiled_pattern_list, - timeout, searchwindowsize, async_) - - def expect_list(self, pattern_list, timeout=-1, searchwindowsize=-1, - async_=False, **kw): - '''This takes a list of compiled regular expressions and returns the - index into the pattern_list that matched the child output. The list may - also contain EOF or TIMEOUT(which are not compiled regular - expressions). This method is similar to the expect() method except that - expect_list() does not recompile the pattern list on every call. This - may help if you are trying to optimize for speed, otherwise just use - the expect() method. This is called by expect(). - - - Like :meth:`expect`, passing ``async_=True`` will make this return an - asyncio coroutine. - ''' - if timeout == -1: - timeout = self.timeout - if 'async' in kw: - async_ = kw.pop('async') - if kw: - raise TypeError("Unknown keyword arguments: {}".format(kw)) - - exp = Expecter(self, searcher_re(pattern_list), searchwindowsize) - if async_: - from ._async import expect_async - return expect_async(exp, timeout) - else: - return exp.expect_loop(timeout) - - def expect_exact(self, pattern_list, timeout=-1, searchwindowsize=-1, - async_=False, **kw): - - '''This is similar to expect(), but uses plain string matching instead - of compiled regular expressions in 'pattern_list'. The 'pattern_list' - may be a string; a list or other sequence of strings; or TIMEOUT and - EOF. - - This call might be faster than expect() for two reasons: string - searching is faster than RE matching and it is possible to limit the - search to just the end of the input buffer. - - This method is also useful when you don't want to have to worry about - escaping regular expression characters that you want to match. - - Like :meth:`expect`, passing ``async_=True`` will make this return an - asyncio coroutine. - ''' - if timeout == -1: - timeout = self.timeout - if 'async' in kw: - async_ = kw.pop('async') - if kw: - raise TypeError("Unknown keyword arguments: {}".format(kw)) - - if (isinstance(pattern_list, self.allowed_string_types) or - pattern_list in (TIMEOUT, EOF)): - pattern_list = [pattern_list] - - def prepare_pattern(pattern): - if pattern in (TIMEOUT, EOF): - return pattern - if isinstance(pattern, self.allowed_string_types): - return self._coerce_expect_string(pattern) - self._pattern_type_err(pattern) - - try: - pattern_list = iter(pattern_list) - except TypeError: - self._pattern_type_err(pattern_list) - pattern_list = [prepare_pattern(p) for p in pattern_list] - - exp = Expecter(self, searcher_string(pattern_list), searchwindowsize) - if async_: - from ._async import expect_async - return expect_async(exp, timeout) - else: - return exp.expect_loop(timeout) - - def expect_loop(self, searcher, timeout=-1, searchwindowsize=-1): - '''This is the common loop used inside expect. The 'searcher' should be - an instance of searcher_re or searcher_string, which describes how and - what to search for in the input. - - See expect() for other arguments, return value and exceptions. ''' - - exp = Expecter(self, searcher, searchwindowsize) - return exp.expect_loop(timeout) - - def read(self, size=-1): - '''This reads at most "size" bytes from the file (less if the read hits - EOF before obtaining size bytes). If the size argument is negative or - omitted, read all data until EOF is reached. The bytes are returned as - a string object. An empty string is returned when EOF is encountered - immediately. ''' - - if size == 0: - return self.string_type() - if size < 0: - # delimiter default is EOF - self.expect(self.delimiter) - return self.before - - # I could have done this more directly by not using expect(), but - # I deliberately decided to couple read() to expect() so that - # I would catch any bugs early and ensure consistent behavior. - # It's a little less efficient, but there is less for me to - # worry about if I have to later modify read() or expect(). - # Note, it's OK if size==-1 in the regex. That just means it - # will never match anything in which case we stop only on EOF. - cre = re.compile(self._coerce_expect_string('.{%d}' % size), re.DOTALL) - # delimiter default is EOF - index = self.expect([cre, self.delimiter]) - if index == 0: - ### FIXME self.before should be ''. Should I assert this? - return self.after - return self.before - - def readline(self, size=-1): - '''This reads and returns one entire line. The newline at the end of - line is returned as part of the string, unless the file ends without a - newline. An empty string is returned if EOF is encountered immediately. - This looks for a newline as a CR/LF pair (\\r\\n) even on UNIX because - this is what the pseudotty device returns. So contrary to what you may - expect you will receive newlines as \\r\\n. - - If the size argument is 0 then an empty string is returned. In all - other cases the size argument is ignored, which is not standard - behavior for a file-like object. ''' - - if size == 0: - return self.string_type() - # delimiter default is EOF - index = self.expect([self.crlf, self.delimiter]) - if index == 0: - return self.before + self.crlf - else: - return self.before - - def __iter__(self): - '''This is to support iterators over a file-like object. - ''' - return iter(self.readline, self.string_type()) - - def readlines(self, sizehint=-1): - '''This reads until EOF using readline() and returns a list containing - the lines thus read. The optional 'sizehint' argument is ignored. - Remember, because this reads until EOF that means the child - process should have closed its stdout. If you run this method on - a child that is still running with its stdout open then this - method will block until it timesout.''' - - lines = [] - while True: - line = self.readline() - if not line: - break - lines.append(line) - return lines - - def fileno(self): - '''Expose file descriptor for a file-like interface - ''' - return self.child_fd - - def flush(self): - '''This does nothing. It is here to support the interface for a - File-like object. ''' - pass - - def isatty(self): - """Overridden in subclass using tty""" - return False - - # For 'with spawn(...) as child:' - def __enter__(self): - return self - - def __exit__(self, etype, evalue, tb): - # We rely on subclasses to implement close(). If they don't, it's not - # clear what a context manager should do. - self.close() diff --git a/lldb/third_party/Python/module/pexpect-4.6/pexpect/utils.py b/lldb/third_party/Python/module/pexpect-4.6/pexpect/utils.py deleted file mode 100644 index f77451960900..000000000000 --- a/lldb/third_party/Python/module/pexpect-4.6/pexpect/utils.py +++ /dev/null @@ -1,187 +0,0 @@ -import os -import sys -import stat -import select -import time -import errno - -try: - InterruptedError -except NameError: - # Alias Python2 exception to Python3 - InterruptedError = select.error - -if sys.version_info[0] >= 3: - string_types = (str,) -else: - string_types = (unicode, str) - - -def is_executable_file(path): - """Checks that path is an executable regular file, or a symlink towards one. - - This is roughly ``os.path isfile(path) and os.access(path, os.X_OK)``. - """ - # follow symlinks, - fpath = os.path.realpath(path) - - if not os.path.isfile(fpath): - # non-files (directories, fifo, etc.) - return False - - mode = os.stat(fpath).st_mode - - if (sys.platform.startswith('sunos') - and os.getuid() == 0): - # When root on Solaris, os.X_OK is True for *all* files, irregardless - # of their executability -- instead, any permission bit of any user, - # group, or other is fine enough. - # - # (This may be true for other "Unix98" OS's such as HP-UX and AIX) - return bool(mode & (stat.S_IXUSR | - stat.S_IXGRP | - stat.S_IXOTH)) - - return os.access(fpath, os.X_OK) - - -def which(filename, env=None): - '''This takes a given filename; tries to find it in the environment path; - then checks if it is executable. This returns the full path to the filename - if found and executable. Otherwise this returns None.''' - - # Special case where filename contains an explicit path. - if os.path.dirname(filename) != '' and is_executable_file(filename): - return filename - if env is None: - env = os.environ - p = env.get('PATH') - if not p: - p = os.defpath - pathlist = p.split(os.pathsep) - for path in pathlist: - ff = os.path.join(path, filename) - if is_executable_file(ff): - return ff - return None - - -def split_command_line(command_line): - - '''This splits a command line into a list of arguments. It splits arguments - on spaces, but handles embedded quotes, doublequotes, and escaped - characters. It's impossible to do this with a regular expression, so I - wrote a little state machine to parse the command line. ''' - - arg_list = [] - arg = '' - - # Constants to name the states we can be in. - state_basic = 0 - state_esc = 1 - state_singlequote = 2 - state_doublequote = 3 - # The state when consuming whitespace between commands. - state_whitespace = 4 - state = state_basic - - for c in command_line: - if state == state_basic or state == state_whitespace: - if c == '\\': - # Escape the next character - state = state_esc - elif c == r"'": - # Handle single quote - state = state_singlequote - elif c == r'"': - # Handle double quote - state = state_doublequote - elif c.isspace(): - # Add arg to arg_list if we aren't in the middle of whitespace. - if state == state_whitespace: - # Do nothing. - None - else: - arg_list.append(arg) - arg = '' - state = state_whitespace - else: - arg = arg + c - state = state_basic - elif state == state_esc: - arg = arg + c - state = state_basic - elif state == state_singlequote: - if c == r"'": - state = state_basic - else: - arg = arg + c - elif state == state_doublequote: - if c == r'"': - state = state_basic - else: - arg = arg + c - - if arg != '': - arg_list.append(arg) - return arg_list - - -def select_ignore_interrupts(iwtd, owtd, ewtd, timeout=None): - - '''This is a wrapper around select.select() that ignores signals. If - select.select raises a select.error exception and errno is an EINTR - error then it is ignored. Mainly this is used to ignore sigwinch - (terminal resize). ''' - - # if select() is interrupted by a signal (errno==EINTR) then - # we loop back and enter the select() again. - if timeout is not None: - end_time = time.time() + timeout - while True: - try: - return select.select(iwtd, owtd, ewtd, timeout) - except InterruptedError: - err = sys.exc_info()[1] - if err.args[0] == errno.EINTR: - # if we loop back we have to subtract the - # amount of time we already waited. - if timeout is not None: - timeout = end_time - time.time() - if timeout < 0: - return([], [], []) - else: - # something else caused the select.error, so - # this actually is an exception. - raise - - -def poll_ignore_interrupts(fds, timeout=None): - '''Simple wrapper around poll to register file descriptors and - ignore signals.''' - - if timeout is not None: - end_time = time.time() + timeout - - poller = select.poll() - for fd in fds: - poller.register(fd, select.POLLIN | select.POLLPRI | select.POLLHUP | select.POLLERR) - - while True: - try: - timeout_ms = None if timeout is None else timeout * 1000 - results = poller.poll(timeout_ms) - return [afd for afd, _ in results] - except InterruptedError: - err = sys.exc_info()[1] - if err.args[0] == errno.EINTR: - # if we loop back we have to subtract the - # amount of time we already waited. - if timeout is not None: - timeout = end_time - time.time() - if timeout < 0: - return [] - else: - # something else caused the select.error, so - # this actually is an exception. - raise diff --git a/lldb/third_party/Python/module/pexpect-4.6/requirements-testing.txt b/lldb/third_party/Python/module/pexpect-4.6/requirements-testing.txt deleted file mode 100644 index 1894122c85c5..000000000000 --- a/lldb/third_party/Python/module/pexpect-4.6/requirements-testing.txt +++ /dev/null @@ -1,5 +0,0 @@ -pytest -pytest-cov -coverage -coveralls -pytest-capturelog diff --git a/lldb/third_party/Python/module/pexpect-4.6/setup.cfg b/lldb/third_party/Python/module/pexpect-4.6/setup.cfg deleted file mode 100644 index b2a82dcdc6c5..000000000000 --- a/lldb/third_party/Python/module/pexpect-4.6/setup.cfg +++ /dev/null @@ -1,5 +0,0 @@ -[tool:pytest] -norecursedirs = .git - -[bdist_wheel] -universal=1 diff --git a/lldb/third_party/Python/module/pexpect-4.6/setup.py b/lldb/third_party/Python/module/pexpect-4.6/setup.py deleted file mode 100644 index 4e61e795c2af..000000000000 --- a/lldb/third_party/Python/module/pexpect-4.6/setup.py +++ /dev/null @@ -1,71 +0,0 @@ -# encoding: utf-8 -from distutils.core import setup -import os -import re -import sys - -if any(a == 'bdist_wheel' for a in sys.argv): - from setuptools import setup - -with open(os.path.join(os.path.dirname(__file__), 'pexpect', '__init__.py'), 'r') as f: - for line in f: - version_match = re.search(r"__version__ = ['\"]([^'\"]*)['\"]", line) - if version_match: - version = version_match.group(1) - break - else: - raise Exception("couldn't find version number") - -long_description = """ -Pexpect is a pure Python module for spawning child applications; controlling -them; and responding to expected patterns in their output. Pexpect works like -Don Libes' Expect. Pexpect allows your script to spawn a child application and -control it as if a human were typing commands. - -Pexpect can be used for automating interactive applications such as ssh, ftp, -passwd, telnet, etc. It can be used to a automate setup scripts for duplicating -software package installations on different servers. It can be used for -automated software testing. Pexpect is in the spirit of Don Libes' Expect, but -Pexpect is pure Python. - -The main features of Pexpect require the pty module in the Python standard -library, which is only available on Unix-like systems. Some features—waiting -for patterns from file descriptors or subprocesses—are also available on -Windows. -""" - -setup(name='pexpect', - version=version, - packages=['pexpect'], - package_data={'pexpect': ['bashrc.sh']}, - description='Pexpect allows easy control of interactive console applications.', - long_description=long_description, - author='Noah Spurrier; Thomas Kluyver; Jeff Quast', - author_email='noah@noah.org, thomas@kluyver.me.uk, contact@jeffquast.com', - url='https://pexpect.readthedocs.io/', - license='ISC license', - platforms='UNIX', - classifiers = [ - 'Development Status :: 5 - Production/Stable', - 'Environment :: Console', - 'Intended Audience :: Developers', - 'Intended Audience :: System Administrators', - 'License :: OSI Approved :: ISC License (ISCL)', - 'Operating System :: POSIX', - 'Operating System :: MacOS :: MacOS X', - 'Programming Language :: Python', - 'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3', - 'Topic :: Software Development', - 'Topic :: Software Development :: Libraries :: Python Modules', - 'Topic :: Software Development :: Quality Assurance', - 'Topic :: Software Development :: Testing', - 'Topic :: System', - 'Topic :: System :: Archiving :: Packaging', - 'Topic :: System :: Installation/Setup', - 'Topic :: System :: Shells', - 'Topic :: System :: Software Distribution', - 'Topic :: Terminals', - ], - install_requires=['ptyprocess>=0.5'], -) diff --git a/lldb/third_party/Python/module/ptyprocess-0.6.0/.gitignore b/lldb/third_party/Python/module/ptyprocess-0.6.0/.gitignore deleted file mode 100644 index 4b46c269a4c2..000000000000 --- a/lldb/third_party/Python/module/ptyprocess-0.6.0/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -__pycache__ -*.pyc - -/build/ -/dist/ -MANIFEST -docs/_build/ diff --git a/lldb/third_party/Python/module/ptyprocess-0.6.0/.travis.yml b/lldb/third_party/Python/module/ptyprocess-0.6.0/.travis.yml deleted file mode 100644 index 34b391808af3..000000000000 --- a/lldb/third_party/Python/module/ptyprocess-0.6.0/.travis.yml +++ /dev/null @@ -1,9 +0,0 @@ -language: python -python: - - "3.6" - - "3.5" - - "3.4" - - "2.7" -# command to run tests -script: py.test --verbose --verbose -sudo: False diff --git a/lldb/third_party/Python/module/ptyprocess-0.6.0/LICENSE b/lldb/third_party/Python/module/ptyprocess-0.6.0/LICENSE deleted file mode 100644 index 9c772742de96..000000000000 --- a/lldb/third_party/Python/module/ptyprocess-0.6.0/LICENSE +++ /dev/null @@ -1,16 +0,0 @@ -Ptyprocess is under the ISC license, as code derived from Pexpect. - http://opensource.org/licenses/ISC - -Copyright (c) 2013-2014, Pexpect development team -Copyright (c) 2012, Noah Spurrier - -PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY PURPOSE -WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE COPYRIGHT NOTICE -AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. THE SOFTWARE IS PROVIDED -"AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE -INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT -SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL -DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING -OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - diff --git a/lldb/third_party/Python/module/ptyprocess-0.6.0/README.rst b/lldb/third_party/Python/module/ptyprocess-0.6.0/README.rst deleted file mode 100644 index b928e8608d1a..000000000000 --- a/lldb/third_party/Python/module/ptyprocess-0.6.0/README.rst +++ /dev/null @@ -1,15 +0,0 @@ -Launch a subprocess in a pseudo terminal (pty), and interact with both the -process and its pty. - -Sometimes, piping stdin and stdout is not enough. There might be a password -prompt that doesn't read from stdin, output that changes when it's going to a -pipe rather than a terminal, or curses-style interfaces that rely on a terminal. -If you need to automate these things, running the process in a pseudo terminal -(pty) is the answer. - -Interface:: - - p = PtyProcessUnicode.spawn(['python']) - p.read(20) - p.write('6+6\n') - p.read(20) diff --git a/lldb/third_party/Python/module/ptyprocess-0.6.0/ptyprocess/__init__.py b/lldb/third_party/Python/module/ptyprocess-0.6.0/ptyprocess/__init__.py deleted file mode 100644 index e633d0cddacd..000000000000 --- a/lldb/third_party/Python/module/ptyprocess-0.6.0/ptyprocess/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -"""Run a subprocess in a pseudo terminal""" -from .ptyprocess import PtyProcess, PtyProcessUnicode, PtyProcessError - -__version__ = '0.6.0' diff --git a/lldb/third_party/Python/module/ptyprocess-0.6.0/ptyprocess/_fork_pty.py b/lldb/third_party/Python/module/ptyprocess-0.6.0/ptyprocess/_fork_pty.py deleted file mode 100644 index a8d05fe5a3d1..000000000000 --- a/lldb/third_party/Python/module/ptyprocess-0.6.0/ptyprocess/_fork_pty.py +++ /dev/null @@ -1,78 +0,0 @@ -"""Substitute for the forkpty system call, to support Solaris. -""" -import os -import errno - -from pty import (STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO, CHILD) -from .util import PtyProcessError - -def fork_pty(): - '''This implements a substitute for the forkpty system call. This - should be more portable than the pty.fork() function. Specifically, - this should work on Solaris. - - Modified 10.06.05 by Geoff Marshall: Implemented __fork_pty() method to - resolve the issue with Python's pty.fork() not supporting Solaris, - particularly ssh. Based on patch to posixmodule.c authored by Noah - Spurrier:: - - http://mail.python.org/pipermail/python-dev/2003-May/035281.html - - ''' - - parent_fd, child_fd = os.openpty() - if parent_fd < 0 or child_fd < 0: - raise OSError("os.openpty() failed") - - pid = os.fork() - if pid == CHILD: - # Child. - os.close(parent_fd) - pty_make_controlling_tty(child_fd) - - os.dup2(child_fd, STDIN_FILENO) - os.dup2(child_fd, STDOUT_FILENO) - os.dup2(child_fd, STDERR_FILENO) - - else: - # Parent. - os.close(child_fd) - - return pid, parent_fd - -def pty_make_controlling_tty(tty_fd): - '''This makes the pseudo-terminal the controlling tty. This should be - more portable than the pty.fork() function. Specifically, this should - work on Solaris. ''' - - child_name = os.ttyname(tty_fd) - - # Disconnect from controlling tty, if any. Raises OSError of ENXIO - # if there was no controlling tty to begin with, such as when - # executed by a cron(1) job. - try: - fd = os.open("/dev/tty", os.O_RDWR | os.O_NOCTTY) - os.close(fd) - except OSError as err: - if err.errno != errno.ENXIO: - raise - - os.setsid() - - # Verify we are disconnected from controlling tty by attempting to open - # it again. We expect that OSError of ENXIO should always be raised. - try: - fd = os.open("/dev/tty", os.O_RDWR | os.O_NOCTTY) - os.close(fd) - raise PtyProcessError("OSError of errno.ENXIO should be raised.") - except OSError as err: - if err.errno != errno.ENXIO: - raise - - # Verify we can open child pty. - fd = os.open(child_name, os.O_RDWR) - os.close(fd) - - # Verify we now have a controlling tty. - fd = os.open("/dev/tty", os.O_WRONLY) - os.close(fd) diff --git a/lldb/third_party/Python/module/ptyprocess-0.6.0/ptyprocess/ptyprocess.py b/lldb/third_party/Python/module/ptyprocess-0.6.0/ptyprocess/ptyprocess.py deleted file mode 100644 index a58741e8335e..000000000000 --- a/lldb/third_party/Python/module/ptyprocess-0.6.0/ptyprocess/ptyprocess.py +++ /dev/null @@ -1,836 +0,0 @@ -import codecs -import errno -import fcntl -import io -import os -import pty -import resource -import signal -import struct -import sys -import termios -import time - -try: - import builtins # Python 3 -except ImportError: - import __builtin__ as builtins # Python 2 - -# Constants -from pty import (STDIN_FILENO, CHILD) - -from .util import which, PtyProcessError - -_platform = sys.platform.lower() - -# Solaris uses internal __fork_pty(). All others use pty.fork(). -_is_solaris = ( - _platform.startswith('solaris') or - _platform.startswith('sunos')) - -if _is_solaris: - use_native_pty_fork = False - from . import _fork_pty -else: - use_native_pty_fork = True - -PY3 = sys.version_info[0] >= 3 - -if PY3: - def _byte(i): - return bytes([i]) -else: - def _byte(i): - return chr(i) - - class FileNotFoundError(OSError): pass - class TimeoutError(OSError): pass - -_EOF, _INTR = None, None - -def _make_eof_intr(): - """Set constants _EOF and _INTR. - - This avoids doing potentially costly operations on module load. - """ - global _EOF, _INTR - if (_EOF is not None) and (_INTR is not None): - return - - # inherit EOF and INTR definitions from controlling process. - try: - from termios import VEOF, VINTR - fd = None - for name in 'stdin', 'stdout': - stream = getattr(sys, '__%s__' % name, None) - if stream is None or not hasattr(stream, 'fileno'): - continue - try: - fd = stream.fileno() - except ValueError: - continue - if fd is None: - # no fd, raise ValueError to fallback on CEOF, CINTR - raise ValueError("No stream has a fileno") - intr = ord(termios.tcgetattr(fd)[6][VINTR]) - eof = ord(termios.tcgetattr(fd)[6][VEOF]) - except (ImportError, OSError, IOError, ValueError, termios.error): - # unless the controlling process is also not a terminal, - # such as cron(1), or when stdin and stdout are both closed. - # Fall-back to using CEOF and CINTR. There - try: - from termios import CEOF, CINTR - (intr, eof) = (CINTR, CEOF) - except ImportError: - # ^C, ^D - (intr, eof) = (3, 4) - - _INTR = _byte(intr) - _EOF = _byte(eof) - -# setecho and setwinsize are pulled out here because on some platforms, we need -# to do this from the child before we exec() - -def _setecho(fd, state): - errmsg = 'setecho() may not be called on this platform (it may still be possible to enable/disable echo when spawning the child process)' - - try: - attr = termios.tcgetattr(fd) - except termios.error as err: - if err.args[0] == errno.EINVAL: - raise IOError(err.args[0], '%s: %s.' % (err.args[1], errmsg)) - raise - - if state: - attr[3] = attr[3] | termios.ECHO - else: - attr[3] = attr[3] & ~termios.ECHO - - try: - # I tried TCSADRAIN and TCSAFLUSH, but these were inconsistent and - # blocked on some platforms. TCSADRAIN would probably be ideal. - termios.tcsetattr(fd, termios.TCSANOW, attr) - except IOError as err: - if err.args[0] == errno.EINVAL: - raise IOError(err.args[0], '%s: %s.' % (err.args[1], errmsg)) - raise - -def _setwinsize(fd, rows, cols): - # Some very old platforms have a bug that causes the value for - # termios.TIOCSWINSZ to be truncated. There was a hack here to work - # around this, but it caused problems with newer platforms so has been - # removed. For details see https://github.com/pexpect/pexpect/issues/39 - TIOCSWINSZ = getattr(termios, 'TIOCSWINSZ', -2146929561) - # Note, assume ws_xpixel and ws_ypixel are zero. - s = struct.pack('HHHH', rows, cols, 0, 0) - fcntl.ioctl(fd, TIOCSWINSZ, s) - -class PtyProcess(object): - '''This class represents a process running in a pseudoterminal. - - The main constructor is the :meth:`spawn` classmethod. - ''' - string_type = bytes - if PY3: - linesep = os.linesep.encode('ascii') - crlf = '\r\n'.encode('ascii') - - @staticmethod - def write_to_stdout(b): - try: - return sys.stdout.buffer.write(b) - except AttributeError: - # If stdout has been replaced, it may not have .buffer - return sys.stdout.write(b.decode('ascii', 'replace')) - else: - linesep = os.linesep - crlf = '\r\n' - write_to_stdout = sys.stdout.write - - encoding = None - - argv = None - env = None - launch_dir = None - - def __init__(self, pid, fd): - _make_eof_intr() # Ensure _EOF and _INTR are calculated - self.pid = pid - self.fd = fd - readf = io.open(fd, 'rb', buffering=0) - writef = io.open(fd, 'wb', buffering=0, closefd=False) - self.fileobj = io.BufferedRWPair(readf, writef) - - self.terminated = False - self.closed = False - self.exitstatus = None - self.signalstatus = None - # status returned by os.waitpid - self.status = None - self.flag_eof = False - # Used by close() to give kernel time to update process status. - # Time in seconds. - self.delayafterclose = 0.1 - # Used by terminate() to give kernel time to update process status. - # Time in seconds. - self.delayafterterminate = 0.1 - - @classmethod - def spawn( - cls, argv, cwd=None, env=None, echo=True, preexec_fn=None, - dimensions=(24, 80)): - '''Start the given command in a child process in a pseudo terminal. - - This does all the fork/exec type of stuff for a pty, and returns an - instance of PtyProcess. - - If preexec_fn is supplied, it will be called with no arguments in the - child process before exec-ing the specified command. - It may, for instance, set signal handlers to SIG_DFL or SIG_IGN. - - Dimensions of the psuedoterminal used for the subprocess can be - specified as a tuple (rows, cols), or the default (24, 80) will be used. - ''' - # Note that it is difficult for this method to fail. - # You cannot detect if the child process cannot start. - # So the only way you can tell if the child process started - # or not is to try to read from the file descriptor. If you get - # EOF immediately then it means that the child is already dead. - # That may not necessarily be bad because you may have spawned a child - # that performs some task; creates no stdout output; and then dies. - - if not isinstance(argv, (list, tuple)): - raise TypeError("Expected a list or tuple for argv, got %r" % argv) - - # Shallow copy of argv so we can modify it - argv = argv[:] - command = argv[0] - - command_with_path = which(command) - if command_with_path is None: - raise FileNotFoundError('The command was not found or was not ' + - 'executable: %s.' % command) - command = command_with_path - argv[0] = command - - # [issue #119] To prevent the case where exec fails and the user is - # stuck interacting with a python child process instead of whatever - # was expected, we implement the solution from - # http://stackoverflow.com/a/3703179 to pass the exception to the - # parent process - - # [issue #119] 1. Before forking, open a pipe in the parent process. - exec_err_pipe_read, exec_err_pipe_write = os.pipe() - - if use_native_pty_fork: - pid, fd = pty.fork() - else: - # Use internal fork_pty, for Solaris - pid, fd = _fork_pty.fork_pty() - - # Some platforms must call setwinsize() and setecho() from the - # child process, and others from the primary process. We do both, - # allowing IOError for either. - - if pid == CHILD: - # set window size - try: - _setwinsize(STDIN_FILENO, *dimensions) - except IOError as err: - if err.args[0] not in (errno.EINVAL, errno.ENOTTY): - raise - - # disable echo if spawn argument echo was unset - if not echo: - try: - _setecho(STDIN_FILENO, False) - except (IOError, termios.error) as err: - if err.args[0] not in (errno.EINVAL, errno.ENOTTY): - raise - - # [issue #119] 3. The child closes the reading end and sets the - # close-on-exec flag for the writing end. - os.close(exec_err_pipe_read) - fcntl.fcntl(exec_err_pipe_write, fcntl.F_SETFD, fcntl.FD_CLOEXEC) - - # Do not allow child to inherit open file descriptors from parent, - # with the exception of the exec_err_pipe_write of the pipe - # Impose ceiling on max_fd: AIX bugfix for users with unlimited - # nofiles where resource.RLIMIT_NOFILE is 2^63-1 and os.closerange() - # occasionally raises out of range error - max_fd = min(1048576, resource.getrlimit(resource.RLIMIT_NOFILE)[0]) - os.closerange(3, exec_err_pipe_write) - os.closerange(exec_err_pipe_write+1, max_fd) - - if cwd is not None: - os.chdir(cwd) - - if preexec_fn is not None: - try: - preexec_fn() - except Exception as e: - ename = type(e).__name__ - tosend = '{}:0:{}'.format(ename, str(e)) - if PY3: - tosend = tosend.encode('utf-8') - - os.write(exec_err_pipe_write, tosend) - os.close(exec_err_pipe_write) - os._exit(1) - - try: - if env is None: - os.execv(command, argv) - else: - os.execvpe(command, argv, env) - except OSError as err: - # [issue #119] 5. If exec fails, the child writes the error - # code back to the parent using the pipe, then exits. - tosend = 'OSError:{}:{}'.format(err.errno, str(err)) - if PY3: - tosend = tosend.encode('utf-8') - os.write(exec_err_pipe_write, tosend) - os.close(exec_err_pipe_write) - os._exit(os.EX_OSERR) - - # Parent - inst = cls(pid, fd) - - # Set some informational attributes - inst.argv = argv - if env is not None: - inst.env = env - if cwd is not None: - inst.launch_dir = cwd - - # [issue #119] 2. After forking, the parent closes the writing end - # of the pipe and reads from the reading end. - os.close(exec_err_pipe_write) - exec_err_data = os.read(exec_err_pipe_read, 4096) - os.close(exec_err_pipe_read) - - # [issue #119] 6. The parent reads eof (a zero-length read) if the - # child successfully performed exec, since close-on-exec made - # successful exec close the writing end of the pipe. Or, if exec - # failed, the parent reads the error code and can proceed - # accordingly. Either way, the parent blocks until the child calls - # exec. - if len(exec_err_data) != 0: - try: - errclass, errno_s, errmsg = exec_err_data.split(b':', 2) - exctype = getattr(builtins, errclass.decode('ascii'), Exception) - - exception = exctype(errmsg.decode('utf-8', 'replace')) - if exctype is OSError: - exception.errno = int(errno_s) - except: - raise Exception('Subprocess failed, got bad error data: %r' - % exec_err_data) - else: - raise exception - - try: - inst.setwinsize(*dimensions) - except IOError as err: - if err.args[0] not in (errno.EINVAL, errno.ENOTTY, errno.ENXIO): - raise - - return inst - - def __repr__(self): - clsname = type(self).__name__ - if self.argv is not None: - args = [repr(self.argv)] - if self.env is not None: - args.append("env=%r" % self.env) - if self.launch_dir is not None: - args.append("cwd=%r" % self.launch_dir) - - return "{}.spawn({})".format(clsname, ", ".join(args)) - - else: - return "{}(pid={}, fd={})".format(clsname, self.pid, self.fd) - - @staticmethod - def _coerce_send_string(s): - if not isinstance(s, bytes): - return s.encode('utf-8') - return s - - @staticmethod - def _coerce_read_string(s): - return s - - def __del__(self): - '''This makes sure that no system resources are left open. Python only - garbage collects Python objects. OS file descriptors are not Python - objects, so they must be handled explicitly. If the child file - descriptor was opened outside of this class (passed to the constructor) - then this does not close it. ''' - - if not self.closed: - # It is possible for __del__ methods to execute during the - # teardown of the Python VM itself. Thus self.close() may - # trigger an exception because os.close may be None. - try: - self.close() - # which exception, shouldn't we catch explicitly .. ? - except: - pass - - - def fileno(self): - '''This returns the file descriptor of the pty for the child. - ''' - return self.fd - - def close(self, force=True): - '''This closes the connection with the child application. Note that - calling close() more than once is valid. This emulates standard Python - behavior with files. Set force to True if you want to make sure that - the child is terminated (SIGKILL is sent if the child ignores SIGHUP - and SIGINT). ''' - if not self.closed: - self.flush() - self.fileobj.close() # Closes the file descriptor - # Give kernel time to update process status. - time.sleep(self.delayafterclose) - if self.isalive(): - if not self.terminate(force): - raise PtyProcessError('Could not terminate the child.') - self.fd = -1 - self.closed = True - #self.pid = None - - def flush(self): - '''This does nothing. It is here to support the interface for a - File-like object. ''' - - pass - - def isatty(self): - '''This returns True if the file descriptor is open and connected to a - tty(-like) device, else False. - - On SVR4-style platforms implementing streams, such as SunOS and HP-UX, - the child pty may not appear as a terminal device. This means - methods such as setecho(), setwinsize(), getwinsize() may raise an - IOError. ''' - - return os.isatty(self.fd) - - def waitnoecho(self, timeout=None): - '''This waits until the terminal ECHO flag is set False. This returns - True if the echo mode is off. This returns False if the ECHO flag was - not set False before the timeout. This can be used to detect when the - child is waiting for a password. Usually a child application will turn - off echo mode when it is waiting for the user to enter a password. For - example, instead of expecting the "password:" prompt you can wait for - the child to set ECHO off:: - - p = pexpect.spawn('ssh user@example.com') - p.waitnoecho() - p.sendline(mypassword) - - If timeout==None then this method to block until ECHO flag is False. - ''' - - if timeout is not None: - end_time = time.time() + timeout - while True: - if not self.getecho(): - return True - if timeout < 0 and timeout is not None: - return False - if timeout is not None: - timeout = end_time - time.time() - time.sleep(0.1) - - def getecho(self): - '''This returns the terminal echo mode. This returns True if echo is - on or False if echo is off. Child applications that are expecting you - to enter a password often set ECHO False. See waitnoecho(). - - Not supported on platforms where ``isatty()`` returns False. ''' - - try: - attr = termios.tcgetattr(self.fd) - except termios.error as err: - errmsg = 'getecho() may not be called on this platform' - if err.args[0] == errno.EINVAL: - raise IOError(err.args[0], '%s: %s.' % (err.args[1], errmsg)) - raise - - self.echo = bool(attr[3] & termios.ECHO) - return self.echo - - def setecho(self, state): - '''This sets the terminal echo mode on or off. Note that anything the - child sent before the echo will be lost, so you should be sure that - your input buffer is empty before you call setecho(). For example, the - following will work as expected:: - - p = pexpect.spawn('cat') # Echo is on by default. - p.sendline('1234') # We expect see this twice from the child... - p.expect(['1234']) # ... once from the tty echo... - p.expect(['1234']) # ... and again from cat itself. - p.setecho(False) # Turn off tty echo - p.sendline('abcd') # We will set this only once (echoed by cat). - p.sendline('wxyz') # We will set this only once (echoed by cat) - p.expect(['abcd']) - p.expect(['wxyz']) - - The following WILL NOT WORK because the lines sent before the setecho - will be lost:: - - p = pexpect.spawn('cat') - p.sendline('1234') - p.setecho(False) # Turn off tty echo - p.sendline('abcd') # We will set this only once (echoed by cat). - p.sendline('wxyz') # We will set this only once (echoed by cat) - p.expect(['1234']) - p.expect(['1234']) - p.expect(['abcd']) - p.expect(['wxyz']) - - - Not supported on platforms where ``isatty()`` returns False. - ''' - _setecho(self.fd, state) - - self.echo = state - - def read(self, size=1024): - """Read and return at most ``size`` bytes from the pty. - - Can block if there is nothing to read. Raises :exc:`EOFError` if the - terminal was closed. - - Unlike Pexpect's ``read_nonblocking`` method, this doesn't try to deal - with the vagaries of EOF on platforms that do strange things, like IRIX - or older Solaris systems. It handles the errno=EIO pattern used on - Linux, and the empty-string return used on BSD platforms and (seemingly) - on recent Solaris. - """ - try: - s = self.fileobj.read1(size) - except (OSError, IOError) as err: - if err.args[0] == errno.EIO: - # Linux-style EOF - self.flag_eof = True - raise EOFError('End Of File (EOF). Exception style platform.') - raise - if s == b'': - # BSD-style EOF (also appears to work on recent Solaris (OpenIndiana)) - self.flag_eof = True - raise EOFError('End Of File (EOF). Empty string style platform.') - - return s - - def readline(self): - """Read one line from the pseudoterminal, and return it as unicode. - - Can block if there is nothing to read. Raises :exc:`EOFError` if the - terminal was closed. - """ - try: - s = self.fileobj.readline() - except (OSError, IOError) as err: - if err.args[0] == errno.EIO: - # Linux-style EOF - self.flag_eof = True - raise EOFError('End Of File (EOF). Exception style platform.') - raise - if s == b'': - # BSD-style EOF (also appears to work on recent Solaris (OpenIndiana)) - self.flag_eof = True - raise EOFError('End Of File (EOF). Empty string style platform.') - - return s - - def _writeb(self, b, flush=True): - n = self.fileobj.write(b) - if flush: - self.fileobj.flush() - return n - - def write(self, s, flush=True): - """Write bytes to the pseudoterminal. - - Returns the number of bytes written. - """ - return self._writeb(s, flush=flush) - - def sendcontrol(self, char): - '''Helper method that wraps send() with mnemonic access for sending control - character to the child (such as Ctrl-C or Ctrl-D). For example, to send - Ctrl-G (ASCII 7, bell, '\a'):: - - child.sendcontrol('g') - - See also, sendintr() and sendeof(). - ''' - char = char.lower() - a = ord(char) - if 97 <= a <= 122: - a = a - ord('a') + 1 - byte = _byte(a) - return self._writeb(byte), byte - d = {'@': 0, '`': 0, - '[': 27, '{': 27, - '\\': 28, '|': 28, - ']': 29, '}': 29, - '^': 30, '~': 30, - '_': 31, - '?': 127} - if char not in d: - return 0, b'' - - byte = _byte(d[char]) - return self._writeb(byte), byte - - def sendeof(self): - '''This sends an EOF to the child. This sends a character which causes - the pending parent output buffer to be sent to the waiting child - program without waiting for end-of-line. If it is the first character - of the line, the read() in the user program returns 0, which signifies - end-of-file. This means to work as expected a sendeof() has to be - called at the beginning of a line. This method does not send a newline. - It is the responsibility of the caller to ensure the eof is sent at the - beginning of a line. ''' - - return self._writeb(_EOF), _EOF - - def sendintr(self): - '''This sends a SIGINT to the child. It does not require - the SIGINT to be the first character on a line. ''' - - return self._writeb(_INTR), _INTR - - def eof(self): - '''This returns True if the EOF exception was ever raised. - ''' - - return self.flag_eof - - def terminate(self, force=False): - '''This forces a child process to terminate. It starts nicely with - SIGHUP and SIGINT. If "force" is True then moves onto SIGKILL. This - returns True if the child was terminated. This returns False if the - child could not be terminated. ''' - - if not self.isalive(): - return True - try: - self.kill(signal.SIGHUP) - time.sleep(self.delayafterterminate) - if not self.isalive(): - return True - self.kill(signal.SIGCONT) - time.sleep(self.delayafterterminate) - if not self.isalive(): - return True - self.kill(signal.SIGINT) - time.sleep(self.delayafterterminate) - if not self.isalive(): - return True - if force: - self.kill(signal.SIGKILL) - time.sleep(self.delayafterterminate) - if not self.isalive(): - return True - else: - return False - return False - except OSError: - # I think there are kernel timing issues that sometimes cause - # this to happen. I think isalive() reports True, but the - # process is dead to the kernel. - # Make one last attempt to see if the kernel is up to date. - time.sleep(self.delayafterterminate) - if not self.isalive(): - return True - else: - return False - - def wait(self): - '''This waits until the child exits. This is a blocking call. This will - not read any data from the child, so this will block forever if the - child has unread output and has terminated. In other words, the child - may have printed output then called exit(), but, the child is - technically still alive until its output is read by the parent. ''' - - if self.isalive(): - pid, status = os.waitpid(self.pid, 0) - else: - return self.exitstatus - self.exitstatus = os.WEXITSTATUS(status) - if os.WIFEXITED(status): - self.status = status - self.exitstatus = os.WEXITSTATUS(status) - self.signalstatus = None - self.terminated = True - elif os.WIFSIGNALED(status): - self.status = status - self.exitstatus = None - self.signalstatus = os.WTERMSIG(status) - self.terminated = True - elif os.WIFSTOPPED(status): # pragma: no cover - # You can't call wait() on a child process in the stopped state. - raise PtyProcessError('Called wait() on a stopped child ' + - 'process. This is not supported. Is some other ' + - 'process attempting job control with our child pid?') - return self.exitstatus - - def isalive(self): - '''This tests if the child process is running or not. This is - non-blocking. If the child was terminated then this will read the - exitstatus or signalstatus of the child. This returns True if the child - process appears to be running or False if not. It can take literally - SECONDS for Solaris to return the right status. ''' - - if self.terminated: - return False - - if self.flag_eof: - # This is for Linux, which requires the blocking form - # of waitpid to get the status of a defunct process. - # This is super-lame. The flag_eof would have been set - # in read_nonblocking(), so this should be safe. - waitpid_options = 0 - else: - waitpid_options = os.WNOHANG - - try: - pid, status = os.waitpid(self.pid, waitpid_options) - except OSError as e: - # No child processes - if e.errno == errno.ECHILD: - raise PtyProcessError('isalive() encountered condition ' + - 'where "terminated" is 0, but there was no child ' + - 'process. Did someone else call waitpid() ' + - 'on our process?') - else: - raise - - # I have to do this twice for Solaris. - # I can't even believe that I figured this out... - # If waitpid() returns 0 it means that no child process - # wishes to report, and the value of status is undefined. - if pid == 0: - try: - ### os.WNOHANG) # Solaris! - pid, status = os.waitpid(self.pid, waitpid_options) - except OSError as e: # pragma: no cover - # This should never happen... - if e.errno == errno.ECHILD: - raise PtyProcessError('isalive() encountered condition ' + - 'that should never happen. There was no child ' + - 'process. Did someone else call waitpid() ' + - 'on our process?') - else: - raise - - # If pid is still 0 after two calls to waitpid() then the process - # really is alive. This seems to work on all platforms, except for - # Irix which seems to require a blocking call on waitpid or select, - # so I let read_nonblocking take care of this situation - # (unfortunately, this requires waiting through the timeout). - if pid == 0: - return True - - if pid == 0: - return True - - if os.WIFEXITED(status): - self.status = status - self.exitstatus = os.WEXITSTATUS(status) - self.signalstatus = None - self.terminated = True - elif os.WIFSIGNALED(status): - self.status = status - self.exitstatus = None - self.signalstatus = os.WTERMSIG(status) - self.terminated = True - elif os.WIFSTOPPED(status): - raise PtyProcessError('isalive() encountered condition ' + - 'where child process is stopped. This is not ' + - 'supported. Is some other process attempting ' + - 'job control with our child pid?') - return False - - def kill(self, sig): - """Send the given signal to the child application. - - In keeping with UNIX tradition it has a misleading name. It does not - necessarily kill the child unless you send the right signal. See the - :mod:`signal` module for constants representing signal numbers. - """ - - # Same as os.kill, but the pid is given for you. - if self.isalive(): - os.kill(self.pid, sig) - - def getwinsize(self): - """Return the window size of the pseudoterminal as a tuple (rows, cols). - """ - TIOCGWINSZ = getattr(termios, 'TIOCGWINSZ', 1074295912) - s = struct.pack('HHHH', 0, 0, 0, 0) - x = fcntl.ioctl(self.fd, TIOCGWINSZ, s) - return struct.unpack('HHHH', x)[0:2] - - def setwinsize(self, rows, cols): - """Set the terminal window size of the child tty. - - This will cause a SIGWINCH signal to be sent to the child. This does not - change the physical window size. It changes the size reported to - TTY-aware applications like vi or curses -- applications that respond to - the SIGWINCH signal. - """ - return _setwinsize(self.fd, rows, cols) - - -class PtyProcessUnicode(PtyProcess): - """Unicode wrapper around a process running in a pseudoterminal. - - This class exposes a similar interface to :class:`PtyProcess`, but its read - methods return unicode, and its :meth:`write` accepts unicode. - """ - if PY3: - string_type = str - else: - string_type = unicode # analysis:ignore - - def __init__(self, pid, fd, encoding='utf-8', codec_errors='strict'): - super(PtyProcessUnicode, self).__init__(pid, fd) - self.encoding = encoding - self.codec_errors = codec_errors - self.decoder = codecs.getincrementaldecoder(encoding)(errors=codec_errors) - - def read(self, size=1024): - """Read at most ``size`` bytes from the pty, return them as unicode. - - Can block if there is nothing to read. Raises :exc:`EOFError` if the - terminal was closed. - - The size argument still refers to bytes, not unicode code points. - """ - b = super(PtyProcessUnicode, self).read(size) - return self.decoder.decode(b, final=False) - - def readline(self): - """Read one line from the pseudoterminal, and return it as unicode. - - Can block if there is nothing to read. Raises :exc:`EOFError` if the - terminal was closed. - """ - b = super(PtyProcessUnicode, self).readline() - return self.decoder.decode(b, final=False) - - def write(self, s): - """Write the unicode string ``s`` to the pseudoterminal. - - Returns the number of bytes written. - """ - b = s.encode(self.encoding) - return super(PtyProcessUnicode, self).write(b) diff --git a/lldb/third_party/Python/module/ptyprocess-0.6.0/ptyprocess/util.py b/lldb/third_party/Python/module/ptyprocess-0.6.0/ptyprocess/util.py deleted file mode 100644 index aadbd62c801d..000000000000 --- a/lldb/third_party/Python/module/ptyprocess-0.6.0/ptyprocess/util.py +++ /dev/null @@ -1,71 +0,0 @@ -try: - from shutil import which # Python >= 3.3 -except ImportError: - import os, sys - - # This is copied from Python 3.4.1 - def which(cmd, mode=os.F_OK | os.X_OK, path=None): - """Given a command, mode, and a PATH string, return the path which - conforms to the given mode on the PATH, or None if there is no such - file. - - `mode` defaults to os.F_OK | os.X_OK. `path` defaults to the result - of os.environ.get("PATH"), or can be overridden with a custom search - path. - - """ - # Check that a given file can be accessed with the correct mode. - # Additionally check that `file` is not a directory, as on Windows - # directories pass the os.access check. - def _access_check(fn, mode): - return (os.path.exists(fn) and os.access(fn, mode) - and not os.path.isdir(fn)) - - # If we're given a path with a directory part, look it up directly rather - # than referring to PATH directories. This includes checking relative to the - # current directory, e.g. ./script - if os.path.dirname(cmd): - if _access_check(cmd, mode): - return cmd - return None - - if path is None: - path = os.environ.get("PATH", os.defpath) - if not path: - return None - path = path.split(os.pathsep) - - if sys.platform == "win32": - # The current directory takes precedence on Windows. - if not os.curdir in path: - path.insert(0, os.curdir) - - # PATHEXT is necessary to check on Windows. - pathext = os.environ.get("PATHEXT", "").split(os.pathsep) - # See if the given file matches any of the expected path extensions. - # This will allow us to short circuit when given "python.exe". - # If it does match, only test that one, otherwise we have to try - # others. - if any(cmd.lower().endswith(ext.lower()) for ext in pathext): - files = [cmd] - else: - files = [cmd + ext for ext in pathext] - else: - # On other platforms you don't have things like PATHEXT to tell you - # what file suffixes are executable, so just pass on cmd as-is. - files = [cmd] - - seen = set() - for dir in path: - normdir = os.path.normcase(dir) - if not normdir in seen: - seen.add(normdir) - for thefile in files: - name = os.path.join(dir, thefile) - if _access_check(name, mode): - return name - return None - - -class PtyProcessError(Exception): - """Generic error class for this package.""" diff --git a/lldb/third_party/Python/module/ptyprocess-0.6.0/pyproject.toml b/lldb/third_party/Python/module/ptyprocess-0.6.0/pyproject.toml deleted file mode 100644 index 881c1bae897d..000000000000 --- a/lldb/third_party/Python/module/ptyprocess-0.6.0/pyproject.toml +++ /dev/null @@ -1,24 +0,0 @@ -[build-system] -requires = ["flit"] -build-backend = "flit.buildapi" - -[tool.flit.metadata] -module = "ptyprocess" -author = "Thomas Kluyver" -author-email = "thomas@kluyver.me.uk" -home-page = "https://github.com/pexpect/ptyprocess" -description-file = "README.rst" -classifiers = [ - "Development Status :: 5 - Production/Stable", - "Environment :: Console", - "Intended Audience :: Developers", - "Intended Audience :: System Administrators", - "License :: OSI Approved :: ISC License (ISCL)", - "Operating System :: POSIX", - "Operating System :: MacOS :: MacOS X", - "Programming Language :: Python", - "Programming Language :: Python :: 2.7", - "Programming Language :: Python :: 3", - "Topic :: Terminals" -] - diff --git a/lldb/third_party/Python/module/ptyprocess-0.6.0/readthedocs.yml b/lldb/third_party/Python/module/ptyprocess-0.6.0/readthedocs.yml deleted file mode 100644 index 8b77f690a1bb..000000000000 --- a/lldb/third_party/Python/module/ptyprocess-0.6.0/readthedocs.yml +++ /dev/null @@ -1,2 +0,0 @@ -python: - version: 3 -- GitLab From 9a3595167d3ee875e3180800cec5f5c3fd170e63 Mon Sep 17 00:00:00 2001 From: Philip Reames Date: Mon, 22 Apr 2024 11:40:48 -0700 Subject: [PATCH 018/732] [RISCV] Add freeze when expanding mul by constant to two or more uses (#89290) topperc pointed this out in review of https://github.com/llvm/llvm-project/pull/88791, but I believe the problem applies here as well. Worth noting is that the code I introduced with this bug was mostly copied from other targets - which also have this bug. --- llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 23 +++++++++++---------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index 82339dd20721..41483c49ae03 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -13430,10 +13430,11 @@ static SDValue expandMul(SDNode *N, SelectionDAG &DAG, if (ScaleShift >= 1 && ScaleShift < 4) { unsigned ShiftAmt = Log2_64((MulAmt & (MulAmt - 1))); SDLoc DL(N); - SDValue Shift1 = DAG.getNode(ISD::SHL, DL, VT, N->getOperand(0), - DAG.getConstant(ShiftAmt, DL, VT)); - SDValue Shift2 = DAG.getNode(ISD::SHL, DL, VT, N->getOperand(0), - DAG.getConstant(ScaleShift, DL, VT)); + SDValue X = DAG.getFreeze(N->getOperand(0)); + SDValue Shift1 = + DAG.getNode(ISD::SHL, DL, VT, X, DAG.getConstant(ShiftAmt, DL, VT)); + SDValue Shift2 = + DAG.getNode(ISD::SHL, DL, VT, X, DAG.getConstant(ScaleShift, DL, VT)); return DAG.getNode(ISD::ADD, DL, VT, Shift1, Shift2); } } @@ -13464,13 +13465,13 @@ static SDValue expandMul(SDNode *N, SelectionDAG &DAG, if (ScaleShift >= 1 && ScaleShift < 4) { unsigned ShiftAmt = Log2_64(((MulAmt - 1) & (MulAmt - 2))); SDLoc DL(N); - SDValue Shift1 = DAG.getNode(ISD::SHL, DL, VT, N->getOperand(0), - DAG.getConstant(ShiftAmt, DL, VT)); - SDValue Shift2 = DAG.getNode(ISD::SHL, DL, VT, N->getOperand(0), - DAG.getConstant(ScaleShift, DL, VT)); - return DAG.getNode( - ISD::ADD, DL, VT, Shift1, - DAG.getNode(ISD::ADD, DL, VT, Shift2, N->getOperand(0))); + SDValue X = DAG.getFreeze(N->getOperand(0)); + SDValue Shift1 = + DAG.getNode(ISD::SHL, DL, VT, X, DAG.getConstant(ShiftAmt, DL, VT)); + SDValue Shift2 = + DAG.getNode(ISD::SHL, DL, VT, X, DAG.getConstant(ScaleShift, DL, VT)); + return DAG.getNode(ISD::ADD, DL, VT, Shift1, + DAG.getNode(ISD::ADD, DL, VT, Shift2, X)); } } -- GitLab From ca1f1c957232b05d6529916bcd769ae1c57ff935 Mon Sep 17 00:00:00 2001 From: js324 Date: Mon, 22 Apr 2024 14:42:57 -0400 Subject: [PATCH 019/732] [BitInt] Expose a _BitInt literal suffix in C++ (#86586) This exposes _BitInt literal suffixes __wb and u__wb as an extension in C++. There is a new Extension warning, and the tests are essentially the same as the existing _BitInt literal tests for C but with a few additional cases. Fixes #85223 --- clang/docs/ReleaseNotes.rst | 1 + .../clang/Basic/DiagnosticCommonKinds.td | 3 + clang/include/clang/Basic/DiagnosticGroups.td | 3 + .../clang/Basic/DiagnosticParseKinds.td | 2 +- clang/include/clang/Lex/LiteralSupport.h | 3 +- clang/lib/Lex/LiteralSupport.cpp | 36 +++- clang/lib/Lex/PPExpressions.cpp | 8 +- clang/lib/Sema/SemaExpr.cpp | 12 +- clang/test/AST/bitint-suffix.cpp | 32 ++++ clang/test/Lexer/bitint-constants-compat.c | 11 +- clang/test/Lexer/bitint-constants.cpp | 178 ++++++++++++++++++ 11 files changed, 273 insertions(+), 16 deletions(-) create mode 100644 clang/test/AST/bitint-suffix.cpp create mode 100644 clang/test/Lexer/bitint-constants.cpp diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index b5b351f3d30a..2b3bafa1c305 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -88,6 +88,7 @@ sections with improvements to Clang's support for those languages. C++ Language Changes -------------------- +- Implemented ``_BitInt`` literal suffixes ``__wb`` or ``__WB`` as a Clang extension with ``unsigned`` modifiers also allowed. (#GH85223). C++20 Feature Support ^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td b/clang/include/clang/Basic/DiagnosticCommonKinds.td index a52bf62e2420..0738f43ca555 100644 --- a/clang/include/clang/Basic/DiagnosticCommonKinds.td +++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td @@ -234,6 +234,9 @@ def err_cxx23_size_t_suffix: Error< def err_size_t_literal_too_large: Error< "%select{signed |}0'size_t' literal is out of range of possible " "%select{signed |}0'size_t' values">; +def ext_cxx_bitint_suffix : Extension< + "'_BitInt' suffix for literals is a Clang extension">, + InGroup; def ext_c23_bitint_suffix : ExtWarn< "'_BitInt' suffix for literals is a C23 extension">, InGroup; diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td index 47747d8704b6..60f87da2a738 100644 --- a/clang/include/clang/Basic/DiagnosticGroups.td +++ b/clang/include/clang/Basic/DiagnosticGroups.td @@ -1520,5 +1520,8 @@ def UnsafeBufferUsage : DiagGroup<"unsafe-buffer-usage", [UnsafeBufferUsageInCon // Warnings and notes InstallAPI verification. def InstallAPIViolation : DiagGroup<"installapi-violation">; +// Warnings related to _BitInt extension +def BitIntExtension : DiagGroup<"bit-int-extension">; + // Warnings about misuse of ExtractAPI options. def ExtractAPIMisuse : DiagGroup<"extractapi-misuse">; diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index 66405095d51d..38174cf3549f 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -1654,7 +1654,7 @@ def warn_ext_int_deprecated : Warning< "'_ExtInt' is deprecated; use '_BitInt' instead">, InGroup; def ext_bit_int : Extension< "'_BitInt' in %select{C17 and earlier|C++}0 is a Clang extension">, - InGroup>; + InGroup; } // end of Parse Issue category. let CategoryName = "Modules Issue" in { diff --git a/clang/include/clang/Lex/LiteralSupport.h b/clang/include/clang/Lex/LiteralSupport.h index 643ddbdad8c8..2ed42d1c5f9a 100644 --- a/clang/include/clang/Lex/LiteralSupport.h +++ b/clang/include/clang/Lex/LiteralSupport.h @@ -80,7 +80,8 @@ public: bool isFloat128 : 1; // 1.0q bool isFract : 1; // 1.0hr/r/lr/uhr/ur/ulr bool isAccum : 1; // 1.0hk/k/lk/uhk/uk/ulk - bool isBitInt : 1; // 1wb, 1uwb (C23) + bool isBitInt : 1; // 1wb, 1uwb (C23) or 1__wb, 1__uwb (Clang extension in C++ + // mode) uint8_t MicrosoftInteger; // Microsoft suffix extension i8, i16, i32, or i64. diff --git a/clang/lib/Lex/LiteralSupport.cpp b/clang/lib/Lex/LiteralSupport.cpp index 438c6d772e6e..9c0cbea5052c 100644 --- a/clang/lib/Lex/LiteralSupport.cpp +++ b/clang/lib/Lex/LiteralSupport.cpp @@ -974,6 +974,7 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling, bool isFixedPointConstant = isFixedPointLiteral(); bool isFPConstant = isFloatingLiteral(); bool HasSize = false; + bool DoubleUnderscore = false; // Loop over all of the characters of the suffix. If we see something bad, // we break out of the loop. @@ -1117,6 +1118,31 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling, if (isImaginary) break; // Cannot be repeated. isImaginary = true; continue; // Success. + case '_': + if (isFPConstant) + break; // Invalid for floats + if (HasSize) + break; + if (DoubleUnderscore) + break; // Cannot be repeated. + if (LangOpts.CPlusPlus && s + 2 < ThisTokEnd && + s[1] == '_') { // s + 2 < ThisTokEnd to ensure some character exists + // after __ + DoubleUnderscore = true; + s += 2; // Skip both '_' + if (s + 1 < ThisTokEnd && + (*s == 'u' || *s == 'U')) { // Ensure some character after 'u'/'U' + isUnsigned = true; + ++s; + } + if (s + 1 < ThisTokEnd && + ((*s == 'w' && *(++s) == 'b') || (*s == 'W' && *(++s) == 'B'))) { + isBitInt = true; + HasSize = true; + continue; + } + } + break; case 'w': case 'W': if (isFPConstant) @@ -1127,9 +1153,9 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling, // wb and WB are allowed, but a mixture of cases like Wb or wB is not. We // explicitly do not support the suffix in C++ as an extension because a // library-based UDL that resolves to a library type may be more - // appropriate there. - if (!LangOpts.CPlusPlus && ((s[0] == 'w' && s[1] == 'b') || - (s[0] == 'W' && s[1] == 'B'))) { + // appropriate there. The same rules apply for __wb/__WB. + if ((!LangOpts.CPlusPlus || DoubleUnderscore) && s + 1 < ThisTokEnd && + ((s[0] == 'w' && s[1] == 'b') || (s[0] == 'W' && s[1] == 'B'))) { isBitInt = true; HasSize = true; ++s; // Skip both characters (2nd char skipped on continue). @@ -1241,7 +1267,9 @@ bool NumericLiteralParser::isValidUDSuffix(const LangOptions &LangOpts, return false; // By C++11 [lex.ext]p10, ud-suffixes starting with an '_' are always valid. - if (Suffix[0] == '_') + // Suffixes starting with '__' (double underscore) are for use by + // the implementation. + if (Suffix.starts_with("_") && !Suffix.starts_with("__")) return true; // In C++11, there are no library suffixes. diff --git a/clang/lib/Lex/PPExpressions.cpp b/clang/lib/Lex/PPExpressions.cpp index 8f25c67ec9df..f267efabd617 100644 --- a/clang/lib/Lex/PPExpressions.cpp +++ b/clang/lib/Lex/PPExpressions.cpp @@ -333,11 +333,11 @@ static bool EvaluateValue(PPValue &Result, Token &PeekTok, DefinedTracker &DT, : diag::ext_cxx23_size_t_suffix : diag::err_cxx23_size_t_suffix); - // 'wb/uwb' literals are a C23 feature. We explicitly do not support the - // suffix in C++ as an extension because a library-based UDL that resolves - // to a library type may be more appropriate there. + // 'wb/uwb' literals are a C23 feature. + // '__wb/__uwb' are a C++ extension. if (Literal.isBitInt) - PP.Diag(PeekTok, PP.getLangOpts().C23 + PP.Diag(PeekTok, PP.getLangOpts().CPlusPlus ? diag::ext_cxx_bitint_suffix + : PP.getLangOpts().C23 ? diag::warn_c23_compat_bitint_suffix : diag::ext_c23_bitint_suffix); diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 092da4a75dc3..5c861467bc10 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -4137,11 +4137,13 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) { // 'wb/uwb' literals are a C23 feature. We support _BitInt as a type in C++, // but we do not currently support the suffix in C++ mode because it's not // entirely clear whether WG21 will prefer this suffix to return a library - // type such as std::bit_int instead of returning a _BitInt. - if (Literal.isBitInt && !getLangOpts().CPlusPlus) - PP.Diag(Tok.getLocation(), getLangOpts().C23 - ? diag::warn_c23_compat_bitint_suffix - : diag::ext_c23_bitint_suffix); + // type such as std::bit_int instead of returning a _BitInt. '__wb/__uwb' + // literals are a C++ extension. + if (Literal.isBitInt) + PP.Diag(Tok.getLocation(), + getLangOpts().CPlusPlus ? diag::ext_cxx_bitint_suffix + : getLangOpts().C23 ? diag::warn_c23_compat_bitint_suffix + : diag::ext_c23_bitint_suffix); // Get the value in the widest-possible width. What is "widest" depends on // whether the literal is a bit-precise integer or not. For a bit-precise diff --git a/clang/test/AST/bitint-suffix.cpp b/clang/test/AST/bitint-suffix.cpp new file mode 100644 index 000000000000..dab2b16c7423 --- /dev/null +++ b/clang/test/AST/bitint-suffix.cpp @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 -ast-dump -Wno-unused %s | FileCheck --strict-whitespace %s + +// CHECK: FunctionDecl 0x{{[^ ]*}} <{{.*}}:[[@LINE+1]]:1, line:{{[0-9]*}}:1> line:[[@LINE+1]]:6 func 'void ()' +void func() { + // Ensure that we calculate the correct type from the literal suffix. + + // Note: 0__wb should create an _BitInt(2) because a signed bit-precise + // integer requires one bit for the sign and one bit for the value, + // at a minimum. + // CHECK: TypedefDecl 0x{{[^ ]*}} col:29 zero_wb 'typeof (0wb)':'_BitInt(2)' + typedef __typeof__(0__wb) zero_wb; + // CHECK: TypedefDecl 0x{{[^ ]*}} col:30 neg_zero_wb 'typeof (-0wb)':'_BitInt(2)' + typedef __typeof__(-0__wb) neg_zero_wb; + // CHECK: TypedefDecl 0x{{[^ ]*}} col:29 one_wb 'typeof (1wb)':'_BitInt(2)' + typedef __typeof__(1__wb) one_wb; + // CHECK: TypedefDecl 0x{{[^ ]*}} col:30 neg_one_wb 'typeof (-1wb)':'_BitInt(2)' + typedef __typeof__(-1__wb) neg_one_wb; + + // CHECK: TypedefDecl 0x{{[^ ]*}} col:30 zero_uwb 'typeof (0uwb)':'unsigned _BitInt(1)' + typedef __typeof__(0__uwb) zero_uwb; + // CHECK: TypedefDecl 0x{{[^ ]*}} col:31 neg_zero_uwb 'typeof (-0uwb)':'unsigned _BitInt(1)' + typedef __typeof__(-0__uwb) neg_zero_uwb; + // CHECK: TypedefDecl 0x{{[^ ]*}} col:30 one_uwb 'typeof (1uwb)':'unsigned _BitInt(1)' + typedef __typeof__(1__uwb) one_uwb; + + // Try a value that is too large to fit in [u]intmax_t. + + // CHECK: TypedefDecl 0x{{[^ ]*}} col:49 huge_uwb 'typeof (18446744073709551616uwb)':'unsigned _BitInt(65)' + typedef __typeof__(18446744073709551616__uwb) huge_uwb; + // CHECK: TypedefDecl 0x{{[^ ]*}} col:48 huge_wb 'typeof (18446744073709551616wb)':'_BitInt(66)' + typedef __typeof__(18446744073709551616__wb) huge_wb; +} diff --git a/clang/test/Lexer/bitint-constants-compat.c b/clang/test/Lexer/bitint-constants-compat.c index 607ae88a6188..d8bff94ef88c 100644 --- a/clang/test/Lexer/bitint-constants-compat.c +++ b/clang/test/Lexer/bitint-constants-compat.c @@ -1,14 +1,23 @@ // RUN: %clang_cc1 -std=c17 -fsyntax-only -verify=ext -Wno-unused %s // RUN: %clang_cc1 -std=c2x -fsyntax-only -verify=compat -Wpre-c2x-compat -Wno-unused %s -// RUN: %clang_cc1 -fsyntax-only -verify=cpp -Wno-unused -x c++ %s +// RUN: %clang_cc1 -fsyntax-only -verify=cpp -Wbit-int-extension -Wno-unused -x c++ %s #if 18446744073709551615uwb // ext-warning {{'_BitInt' suffix for literals is a C23 extension}} \ compat-warning {{'_BitInt' suffix for literals is incompatible with C standards before C23}} \ cpp-error {{invalid suffix 'uwb' on integer constant}} #endif +#if 18446744073709551615__uwb // ext-error {{invalid suffix '__uwb' on integer constant}} \ + compat-error {{invalid suffix '__uwb' on integer constant}} \ + cpp-warning {{'_BitInt' suffix for literals is a Clang extension}} +#endif + void func(void) { 18446744073709551615wb; // ext-warning {{'_BitInt' suffix for literals is a C23 extension}} \ compat-warning {{'_BitInt' suffix for literals is incompatible with C standards before C23}} \ cpp-error {{invalid suffix 'wb' on integer constant}} + + 18446744073709551615__wb; // ext-error {{invalid suffix '__wb' on integer constant}} \ + compat-error {{invalid suffix '__wb' on integer constant}} \ + cpp-warning {{'_BitInt' suffix for literals is a Clang extension}} } diff --git a/clang/test/Lexer/bitint-constants.cpp b/clang/test/Lexer/bitint-constants.cpp new file mode 100644 index 000000000000..fb6ac35467cd --- /dev/null +++ b/clang/test/Lexer/bitint-constants.cpp @@ -0,0 +1,178 @@ +// RUN: %clang_cc1 -triple aarch64-unknown-unknown -fsyntax-only -verify -Wno-unused %s + +// Test that the preprocessor behavior makes sense. +#if 1__wb != 1 +#error "wb suffix must be recognized by preprocessor" +#endif +#if 1__uwb != 1 +#error "uwb suffix must be recognized by preprocessor" +#endif +#if !(-1__wb < 0) +#error "wb suffix must be interpreted as signed" +#endif +#if !(-1__uwb > 0) +#error "uwb suffix must be interpreted as unsigned" +#endif + +#if 18446744073709551615__uwb != 18446744073709551615ULL +#error "expected the max value for uintmax_t to compare equal" +#endif + +// Test that the preprocessor gives appropriate diagnostics when the +// literal value is larger than what can be stored in a [u]intmax_t. +#if 18446744073709551616__wb != 0ULL // expected-error {{integer literal is too large to be represented in any integer type}} +#error "never expected to get here due to error" +#endif +#if 18446744073709551616__uwb != 0ULL // expected-error {{integer literal is too large to be represented in any integer type}} +#error "never expected to get here due to error" +#endif + +// Despite using a bit-precise integer, this is expected to overflow +// because all preprocessor arithmetic is done in [u]intmax_t, so this +// should result in the value 0. +#if 18446744073709551615__uwb + 1 != 0ULL +#error "expected modulo arithmetic with uintmax_t width" +#endif + +// Because this bit-precise integer is signed, it will also overflow, +// but Clang handles that by converting to uintmax_t instead of +// intmax_t. +#if 18446744073709551615__wb + 1 != 0LL // expected-warning {{integer literal is too large to be represented in a signed integer type, interpreting as unsigned}} +#error "expected modulo arithmetic with uintmax_t width" +#endif + +// Test that just because the preprocessor can't figure out the bit +// width doesn't mean we can't form the constant, it just means we +// can't use the value in a preprocessor conditional. +unsigned _BitInt(65) Val = 18446744073709551616__uwb; +// UDL test to make sure underscore parsing is correct +unsigned operator ""_(const char *); + +void ValidSuffix(void) { + // Decimal literals. + 1__wb; + 1__WB; + -1__wb; + _Static_assert((int)1__wb == 1, "not 1?"); + _Static_assert((int)-1__wb == -1, "not -1?"); + + 1__uwb; + 1__uWB; + 1__Uwb; + 1__UWB; + 1u__wb; + 1__WBu; + 1U__WB; + _Static_assert((unsigned int)1__uwb == 1u, "not 1?"); + + 1'2__wb; + 1'2__uwb; + _Static_assert((int)1'2__wb == 12, "not 12?"); + _Static_assert((unsigned int)1'2__uwb == 12u, "not 12?"); + + // Hexadecimal literals. + 0x1__wb; + 0x1__uwb; + 0x0'1'2'3__wb; + 0xA'B'c'd__uwb; + _Static_assert((int)0x0'1'2'3__wb == 0x0123, "not 0x0123"); + _Static_assert((unsigned int)0xA'B'c'd__uwb == 0xABCDu, "not 0xABCD"); + + // Binary literals. + 0b1__wb; + 0b1__uwb; + 0b1'0'1'0'0'1__wb; + 0b0'1'0'1'1'0__uwb; + _Static_assert((int)0b1__wb == 1, "not 1?"); + _Static_assert((unsigned int)0b1__uwb == 1u, "not 1?"); + + // Octal literals. + 01__wb; + 01__uwb; + 0'6'0__wb; + 0'0'1__uwb; + 0__wbu; + 0__WBu; + 0U__wb; + 0U__WB; + 0__wb; + _Static_assert((int)0__wb == 0, "not 0?"); + _Static_assert((unsigned int)0__wbu == 0u, "not 0?"); + + // Imaginary or Complex. These are allowed because _Complex can work with any + // integer type, and that includes _BitInt. + 1__wbi; + 1i__wb; + 1__wbj; + + //UDL test as single underscore + unsigned i = 1.0_; +} + +void InvalidSuffix(void) { + // Can't mix the case of wb or WB, and can't rearrange the letters. + 0__wB; // expected-error {{invalid suffix '__wB' on integer constant}} + 0__Wb; // expected-error {{invalid suffix '__Wb' on integer constant}} + 0__bw; // expected-error {{invalid suffix '__bw' on integer constant}} + 0__BW; // expected-error {{invalid suffix '__BW' on integer constant}} + + // Trailing digit separators should still diagnose. + 1'2'__wb; // expected-error {{digit separator cannot appear at end of digit sequence}} + 1'2'__uwb; // expected-error {{digit separator cannot appear at end of digit sequence}} + + // Long. + 1l__wb; // expected-error {{invalid suffix}} + 1__wbl; // expected-error {{invalid suffix}} + 1l__uwb; // expected-error {{invalid suffix}} + 1__l; // expected-error {{invalid suffix}} + 1ul__wb; // expected-error {{invalid suffix}} + + // Long long. + 1ll__wb; // expected-error {{invalid suffix}} + 1__uwbll; // expected-error {{invalid suffix}} + + // Floating point. + 0.1__wb; // expected-error {{invalid suffix}} + 0.1f__wb; // expected-error {{invalid suffix}} + + // Repetitive suffix. + 1__wb__wb; // expected-error {{invalid suffix}} + 1__uwbuwb; // expected-error {{invalid suffix}} + 1__wbuwb; // expected-error {{invalid suffix}} + 1__uwbwb; // expected-error {{invalid suffix}} + + // Missing or extra characters in suffix. + 1__; // expected-error {{invalid suffix}} + 1__u; // expected-error {{invalid suffix}} + 1___; // expected-error {{invalid suffix}} + 1___WB; // expected-error {{invalid suffix}} + 1__wb__; // expected-error {{invalid suffix}} + 1__w; // expected-error {{invalid suffix}} + 1__b; // expected-error {{invalid suffix}} +} + +void ValidSuffixInvalidValue(void) { + // This is a valid suffix, but the value is larger than one that fits within + // the width of BITINT_MAXWIDTH. When this value changes in the future, the + // test cases should pick a new value that can't be represented by a _BitInt, + // but also add a test case that a 129-bit literal still behaves as-expected. + _Static_assert(__BITINT_MAXWIDTH__ <= 128, + "Need to pick a bigger constant for the test case below."); + 0xFFFF'FFFF'FFFF'FFFF'FFFF'FFFF'FFFF'FFFF'1__wb; // expected-error {{integer literal is too large to be represented in any signed integer type}} + 0xFFFF'FFFF'FFFF'FFFF'FFFF'FFFF'FFFF'FFFF'1__uwb; // expected-error {{integer literal is too large to be represented in any integer type}} +} + +void TestTypes(void) { + // 2 value bits, one sign bit + _Static_assert(__is_same(decltype(3__wb), _BitInt(3))); + // 2 value bits, one sign bit + _Static_assert(__is_same(decltype(-3__wb), _BitInt(3))); + // 2 value bits, no sign bit + _Static_assert(__is_same(decltype(3__uwb), unsigned _BitInt(2))); + // 4 value bits, one sign bit + _Static_assert(__is_same(decltype(0xF__wb), _BitInt(5))); + // 4 value bits, one sign bit + _Static_assert(__is_same(decltype(-0xF__wb), _BitInt(5))); + // 4 value bits, no sign bit + _Static_assert(__is_same(decltype(0xF__uwb), unsigned _BitInt(4))); +} -- GitLab From 43c26bbc425dbd8caee311a0d5e4d90c8e71d0d8 Mon Sep 17 00:00:00 2001 From: Nick Desaulniers Date: Mon, 22 Apr 2024 11:50:59 -0700 Subject: [PATCH 020/732] [libc] don't over include stdlib in the hdr declaring bsearch (#89471) When building overlay mode with GCC in release mode, glibc's stdlib.h contains an extern inline declaration of bsearch. This breaks our use of the gnu::alias function attribute in LLVM_LIBC_FUNCTION with GCC because GCC checks that the aliasee is defined in the same TU (clang does not). We're looking at also potentially updating our definition of LLVM_LIBC_FUNCTION from libc/src/__support/common.h. Upon testing, I was able to get -Wnonnull-compare diagnostics from GCC in our definition of bsearch because glibc declares bsearch with the fugly nonnull function attribute. There's more we can do here though to improve our implementation of bsearch. 7.24.5.1 says: Pointer arguments on such a call shall still have valid values, as described in 7.1.4. We could also use either function attributes or parameter attributes to denote these should not be null (for users/callers) and perhaps still check for non-null explicitly under some yet to be discussed hardening configurations in the future. Link: #60481 Link: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-nonnull-function-attribute --- libc/src/stdlib/bsearch.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libc/src/stdlib/bsearch.h b/libc/src/stdlib/bsearch.h index 1de7e051ff6c..3590198ba557 100644 --- a/libc/src/stdlib/bsearch.h +++ b/libc/src/stdlib/bsearch.h @@ -9,7 +9,7 @@ #ifndef LLVM_LIBC_SRC_STDLIB_BSEARCH_H #define LLVM_LIBC_SRC_STDLIB_BSEARCH_H -#include +#include // size_t namespace LIBC_NAMESPACE { -- GitLab From a54102a093190f3a29add5d9327e62f13fce896a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20Degioanni?= Date: Mon, 22 Apr 2024 20:54:22 +0200 Subject: [PATCH 021/732] [llvm] Add support for zero-width integers in MathExtras.h (#87193) MLIR uses zero-width integers, but also re-uses integer logic from LLVM to avoid duplication. This creates issues when LLVM logic is used in MLIR on integers which can be zero-width. In order to avoid special-casing the bitwidth-related logic in MLIR, this PR adds support for zero-width integers in LLVM's MathExtras (and consequently APInt). While most of the logic in theory works the same way out of the box, because bitshifting right by the entire bitwidth in C++ is undefined behavior instead of being zero, some special cases had to be added. Fortunately, it seems like the performance penalty is small. In x86, this usually yields the addition of a predicated conditional move. I checked that no branch is inserted in Arm too. This happens to fix a crash in `arith.extsi` canonicalization in MLIR. I think a follow-up PR to add tests for i0 in arith would be beneficial. --- llvm/include/llvm/Support/MathExtras.h | 58 ++++++++++++++--------- llvm/unittests/ADT/APIntTest.cpp | 3 ++ llvm/unittests/Support/MathExtrasTest.cpp | 8 ++++ 3 files changed, 47 insertions(+), 22 deletions(-) diff --git a/llvm/include/llvm/Support/MathExtras.h b/llvm/include/llvm/Support/MathExtras.h index aa4f4d2ed42e..f0e4ee534ece 100644 --- a/llvm/include/llvm/Support/MathExtras.h +++ b/llvm/include/llvm/Support/MathExtras.h @@ -66,7 +66,9 @@ template T maskTrailingOnes(unsigned N) { static_assert(std::is_unsigned_v, "Invalid type!"); const unsigned Bits = CHAR_BIT * sizeof(T); assert(N <= Bits && "Invalid bit index"); - return N == 0 ? 0 : (T(-1) >> (Bits - N)); + if (N == 0) + return 0; + return T(-1) >> (Bits - N); } /// Create a bitmask with the N left-most bits set to 1, and all other @@ -149,6 +151,8 @@ constexpr inline uint64_t Make_64(uint32_t High, uint32_t Low) { /// Checks if an integer fits into the given bit width. template constexpr inline bool isInt(int64_t x) { + if constexpr (N == 0) + return 0 == x; if constexpr (N == 8) return static_cast(x) == x; if constexpr (N == 16) @@ -164,15 +168,15 @@ template constexpr inline bool isInt(int64_t x) { /// Checks if a signed integer is an N bit number shifted left by S. template constexpr inline bool isShiftedInt(int64_t x) { - static_assert( - N > 0, "isShiftedInt<0> doesn't make sense (refers to a 0-bit number."); + static_assert(S < 64, "isShiftedInt with S >= 64 is too much."); static_assert(N + S <= 64, "isShiftedInt with N + S > 64 is too wide."); return isInt(x) && (x % (UINT64_C(1) << S) == 0); } /// Checks if an unsigned integer fits into the given bit width. template constexpr inline bool isUInt(uint64_t x) { - static_assert(N > 0, "isUInt<0> doesn't make sense"); + if constexpr (N == 0) + return 0 == x; if constexpr (N == 8) return static_cast(x) == x; if constexpr (N == 16) @@ -188,39 +192,46 @@ template constexpr inline bool isUInt(uint64_t x) { /// Checks if a unsigned integer is an N bit number shifted left by S. template constexpr inline bool isShiftedUInt(uint64_t x) { - static_assert( - N > 0, "isShiftedUInt<0> doesn't make sense (refers to a 0-bit number)"); + static_assert(S < 64, "isShiftedUInt with S >= 64 is too much."); static_assert(N + S <= 64, "isShiftedUInt with N + S > 64 is too wide."); - // Per the two static_asserts above, S must be strictly less than 64. So - // 1 << S is not undefined behavior. + // S must be strictly less than 64. So 1 << S is not undefined behavior. return isUInt(x) && (x % (UINT64_C(1) << S) == 0); } /// Gets the maximum value for a N-bit unsigned integer. inline uint64_t maxUIntN(uint64_t N) { - assert(N > 0 && N <= 64 && "integer width out of range"); + assert(N <= 64 && "integer width out of range"); // uint64_t(1) << 64 is undefined behavior, so we can't do // (uint64_t(1) << N) - 1 // without checking first that N != 64. But this works and doesn't have a - // branch. + // branch for N != 0. + // Unfortunately, shifting a uint64_t right by 64 bit is undefined + // behavior, so the condition on N == 0 is necessary. Fortunately, most + // optimizers do not emit branches for this check. + if (N == 0) + return 0; return UINT64_MAX >> (64 - N); } /// Gets the minimum value for a N-bit signed integer. inline int64_t minIntN(int64_t N) { - assert(N > 0 && N <= 64 && "integer width out of range"); + assert(N <= 64 && "integer width out of range"); + if (N == 0) + return 0; return UINT64_C(1) + ~(UINT64_C(1) << (N - 1)); } /// Gets the maximum value for a N-bit signed integer. inline int64_t maxIntN(int64_t N) { - assert(N > 0 && N <= 64 && "integer width out of range"); + assert(N <= 64 && "integer width out of range"); // This relies on two's complement wraparound when N == 64, so we convert to // int64_t only at the very end to avoid UB. + if (N == 0) + return 0; return (UINT64_C(1) << (N - 1)) - 1; } @@ -432,34 +443,38 @@ inline uint64_t alignDown(uint64_t Value, uint64_t Align, uint64_t Skew = 0) { } /// Sign-extend the number in the bottom B bits of X to a 32-bit integer. -/// Requires 0 < B <= 32. +/// Requires B <= 32. template constexpr inline int32_t SignExtend32(uint32_t X) { - static_assert(B > 0, "Bit width can't be 0."); static_assert(B <= 32, "Bit width out of range."); + if constexpr (B == 0) + return 0; return int32_t(X << (32 - B)) >> (32 - B); } /// Sign-extend the number in the bottom B bits of X to a 32-bit integer. -/// Requires 0 < B <= 32. +/// Requires B <= 32. inline int32_t SignExtend32(uint32_t X, unsigned B) { - assert(B > 0 && "Bit width can't be 0."); assert(B <= 32 && "Bit width out of range."); + if (B == 0) + return 0; return int32_t(X << (32 - B)) >> (32 - B); } /// Sign-extend the number in the bottom B bits of X to a 64-bit integer. -/// Requires 0 < B <= 64. +/// Requires B <= 64. template constexpr inline int64_t SignExtend64(uint64_t x) { - static_assert(B > 0, "Bit width can't be 0."); static_assert(B <= 64, "Bit width out of range."); + if constexpr (B == 0) + return 0; return int64_t(x << (64 - B)) >> (64 - B); } /// Sign-extend the number in the bottom B bits of X to a 64-bit integer. -/// Requires 0 < B <= 64. +/// Requires B <= 64. inline int64_t SignExtend64(uint64_t X, unsigned B) { - assert(B > 0 && "Bit width can't be 0."); assert(B <= 64 && "Bit width out of range."); + if (B == 0) + return 0; return int64_t(X << (64 - B)) >> (64 - B); } @@ -564,7 +579,6 @@ SaturatingMultiplyAdd(T X, T Y, T A, bool *ResultOverflowed = nullptr) { /// Use this rather than HUGE_VALF; the latter causes warnings on MSVC. extern const float huge_valf; - /// Add two signed integers, computing the two's complement truncated result, /// returning true if overflow occurred. template @@ -644,6 +658,6 @@ std::enable_if_t, T> MulOverflow(T X, T Y, T &Result) { return UX > (static_cast(std::numeric_limits::max())) / UY; } -} // End llvm namespace +} // namespace llvm #endif diff --git a/llvm/unittests/ADT/APIntTest.cpp b/llvm/unittests/ADT/APIntTest.cpp index 76fc26412407..46aaa47ee645 100644 --- a/llvm/unittests/ADT/APIntTest.cpp +++ b/llvm/unittests/ADT/APIntTest.cpp @@ -2797,6 +2797,9 @@ TEST(APIntTest, sext) { EXPECT_EQ(63U, i32_neg1.countl_one()); EXPECT_EQ(0U, i32_neg1.countr_zero()); EXPECT_EQ(63U, i32_neg1.popcount()); + + EXPECT_EQ(APInt(32u, 0), APInt(0u, 0).sext(32)); + EXPECT_EQ(APInt(64u, 0), APInt(0u, 0).sext(64)); } TEST(APIntTest, trunc) { diff --git a/llvm/unittests/Support/MathExtrasTest.cpp b/llvm/unittests/Support/MathExtrasTest.cpp index 72c765d9ba30..218655851ca0 100644 --- a/llvm/unittests/Support/MathExtrasTest.cpp +++ b/llvm/unittests/Support/MathExtrasTest.cpp @@ -41,6 +41,9 @@ TEST(MathExtras, onesMask) { TEST(MathExtras, isIntN) { EXPECT_TRUE(isIntN(16, 32767)); EXPECT_FALSE(isIntN(16, 32768)); + EXPECT_TRUE(isUIntN(0, 0)); + EXPECT_FALSE(isUIntN(0, 1)); + EXPECT_FALSE(isUIntN(0, -1)); } TEST(MathExtras, isUIntN) { @@ -48,6 +51,8 @@ TEST(MathExtras, isUIntN) { EXPECT_FALSE(isUIntN(16, 65536)); EXPECT_TRUE(isUIntN(1, 0)); EXPECT_TRUE(isUIntN(6, 63)); + EXPECT_TRUE(isUIntN(0, 0)); + EXPECT_FALSE(isUIntN(0, 1)); } TEST(MathExtras, maxIntN) { @@ -55,6 +60,7 @@ TEST(MathExtras, maxIntN) { EXPECT_EQ(2147483647, maxIntN(32)); EXPECT_EQ(std::numeric_limits::max(), maxIntN(32)); EXPECT_EQ(std::numeric_limits::max(), maxIntN(64)); + EXPECT_EQ(0, maxIntN(0)); } TEST(MathExtras, minIntN) { @@ -62,6 +68,7 @@ TEST(MathExtras, minIntN) { EXPECT_EQ(-64LL, minIntN(7)); EXPECT_EQ(std::numeric_limits::min(), minIntN(32)); EXPECT_EQ(std::numeric_limits::min(), minIntN(64)); + EXPECT_EQ(0, minIntN(0)); } TEST(MathExtras, maxUIntN) { @@ -70,6 +77,7 @@ TEST(MathExtras, maxUIntN) { EXPECT_EQ(0xffffffffffffffffULL, maxUIntN(64)); EXPECT_EQ(1ULL, maxUIntN(1)); EXPECT_EQ(0x0fULL, maxUIntN(4)); + EXPECT_EQ(0, maxUIntN(0)); } TEST(MathExtras, reverseBits) { -- GitLab From 0336116ed463c2ad125793a5aa4d7290a2155709 Mon Sep 17 00:00:00 2001 From: Nick Desaulniers Date: Mon, 22 Apr 2024 11:57:28 -0700 Subject: [PATCH 022/732] [libc][docs] codify Policy on Assembler Sources (#88185) It would be helpful in future code reviews to document a policy with regards to where and when Assembler sources are appropriate. That way when reviewers point out infractions, they can point to this written policy, which may help contributors understand that it's not solely the personal preferences of individual reviewers but instead rather a previously agreed upon rule by maintainers. Link: https://github.com/llvm/llvm-project/pull/87837 Link: https://github.com/llvm/llvm-project/pull/88157 Link: https://discourse.llvm.org/t/hand-written-in-assembly-in-libc-setjmp-longjmp/73249/12 --- libc/docs/dev/code_style.rst | 41 ++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/libc/docs/dev/code_style.rst b/libc/docs/dev/code_style.rst index ee4e4257c9fa..170ef6598a9d 100644 --- a/libc/docs/dev/code_style.rst +++ b/libc/docs/dev/code_style.rst @@ -219,3 +219,44 @@ defines. Code under ``libc/src/`` should ``#include`` a proxy header from ``hdr/``, which contains a guard on ``LLVM_LIBC_FULL_BUILD`` to either include our header from ``libc/include/`` (fullbuild) or the corresponding underlying system header (overlay). + +Policy on Assembly sources +========================== + +Coding in high level languages such as C++ provides benefits relative to low +level languages like Assembly, such as: + +* Improved safety +* Compile time diagnostics +* Instrumentation + + * Code coverage + * Profile collection +* Sanitization +* Automatic generation of debug info + +While it's not impossible to have Assembly code that correctly provides all of +the above, we do not wish to maintain such Assembly sources in llvm-libc. + +That said, there are a few functions provided by llvm-libc that are impossible +to reliably implement in C++ for all compilers supported for building +llvm-libc. + +We do use inline or out-of-line Assembly in an intentionally minimal set of +places; typically places where the stack or individual register state must be +manipulated very carefully for correctness, or instances where a specific +instruction sequence does not have a corresponding compiler builtin function +today. + +Contributions adding functions implemented purely in Assembly for performance +are not welcome. + +Contributors should strive to stick with C++ for as long as it remains +reasonable to do so. Ideally, bugs should be filed against compiler vendors, +and links to those bug reports should appear in commit messages or comments +that seek to add Assembly to llvm-libc. + +Patches containing any amount of Assembly ideally should be approved by 2 +maintainers. llvm-libc maintainers reserve the right to reject Assembly +contributions that they feel could be better maintained if rewritten in C++, +and to revisit this policy in the future. -- GitLab From dd7963239e94bcd46e56ae90b08d2d0c9904ff00 Mon Sep 17 00:00:00 2001 From: Nick Desaulniers Date: Mon, 22 Apr 2024 12:03:27 -0700 Subject: [PATCH 023/732] [libc][POSIX][pthreads] implement pthread_rwlockattr_t functions (#89322) Implement: - pthread_rwlockattr_destroy - pthread_rwlockattr_getpshared - pthread_rwlockattr_init - pthread_rwlockattr_setpshared --- libc/config/linux/api.td | 6 +- libc/config/linux/x86_64/entrypoints.txt | 4 ++ libc/include/CMakeLists.txt | 5 +- libc/include/llvm-libc-types/CMakeLists.txt | 1 + .../llvm-libc-types/pthread_rwlockattr_t.h | 15 +++++ libc/spec/posix.td | 26 ++++++++ libc/src/pthread/CMakeLists.txt | 41 ++++++++++++ .../pthread/pthread_rwlockattr_destroy.cpp | 24 +++++++ libc/src/pthread/pthread_rwlockattr_destroy.h | 20 ++++++ .../pthread/pthread_rwlockattr_getpshared.cpp | 23 +++++++ .../pthread/pthread_rwlockattr_getpshared.h | 21 ++++++ libc/src/pthread/pthread_rwlockattr_init.cpp | 23 +++++++ libc/src/pthread/pthread_rwlockattr_init.h | 20 ++++++ .../pthread/pthread_rwlockattr_setpshared.cpp | 27 ++++++++ .../pthread/pthread_rwlockattr_setpshared.h | 20 ++++++ libc/test/src/pthread/CMakeLists.txt | 17 ++++- .../src/pthread/pthread_rwlockattr_test.cpp | 64 +++++++++++++++++++ 17 files changed, 352 insertions(+), 5 deletions(-) create mode 100644 libc/include/llvm-libc-types/pthread_rwlockattr_t.h create mode 100644 libc/src/pthread/pthread_rwlockattr_destroy.cpp create mode 100644 libc/src/pthread/pthread_rwlockattr_destroy.h create mode 100644 libc/src/pthread/pthread_rwlockattr_getpshared.cpp create mode 100644 libc/src/pthread/pthread_rwlockattr_getpshared.h create mode 100644 libc/src/pthread/pthread_rwlockattr_init.cpp create mode 100644 libc/src/pthread/pthread_rwlockattr_init.h create mode 100644 libc/src/pthread/pthread_rwlockattr_setpshared.cpp create mode 100644 libc/src/pthread/pthread_rwlockattr_setpshared.h create mode 100644 libc/test/src/pthread/pthread_rwlockattr_test.cpp diff --git a/libc/config/linux/api.td b/libc/config/linux/api.td index 5fb92a9c299c..7843513c4d27 100644 --- a/libc/config/linux/api.td +++ b/libc/config/linux/api.td @@ -176,11 +176,12 @@ def PThreadAPI : PublicAPI<"pthread.h"> { "__pthread_tss_dtor_t", "pthread_attr_t", "pthread_condattr_t", + "pthread_key_t", "pthread_mutex_t", "pthread_mutexattr_t", - "pthread_t", - "pthread_key_t", "pthread_once_t", + "pthread_rwlockattr_t", + "pthread_t", ]; } @@ -259,6 +260,7 @@ def SysTypesAPI : PublicAPI<"sys/types.h"> { "pthread_mutex_t", "pthread_mutexattr_t", "pthread_once_t", + "pthread_rwlockattr_t", "pthread_t", "size_t", "ssize_t", diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt index 2d8136536b21..a8e289927667 100644 --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -669,6 +669,10 @@ if(LLVM_LIBC_FULL_BUILD) libc.src.pthread.pthread_mutexattr_setrobust libc.src.pthread.pthread_mutexattr_settype libc.src.pthread.pthread_once + libc.src.pthread.pthread_rwlockattr_destroy + libc.src.pthread.pthread_rwlockattr_getpshared + libc.src.pthread.pthread_rwlockattr_init + libc.src.pthread.pthread_rwlockattr_setpshared libc.src.pthread.pthread_setspecific # sched.h entrypoints diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt index f5ba2791af3f..aeef46aabfce 100644 --- a/libc/include/CMakeLists.txt +++ b/libc/include/CMakeLists.txt @@ -322,11 +322,12 @@ add_gen_header( .llvm-libc-types.__pthread_tss_dtor_t .llvm-libc-types.pthread_attr_t .llvm-libc-types.pthread_condattr_t + .llvm-libc-types.pthread_key_t .llvm-libc-types.pthread_mutex_t .llvm-libc-types.pthread_mutexattr_t - .llvm-libc-types.pthread_t - .llvm-libc-types.pthread_key_t .llvm-libc-types.pthread_once_t + .llvm-libc-types.pthread_rwlockattr_t + .llvm-libc-types.pthread_t ) add_gen_header( diff --git a/libc/include/llvm-libc-types/CMakeLists.txt b/libc/include/llvm-libc-types/CMakeLists.txt index f26fc0729dc9..310374fb62ff 100644 --- a/libc/include/llvm-libc-types/CMakeLists.txt +++ b/libc/include/llvm-libc-types/CMakeLists.txt @@ -54,6 +54,7 @@ add_header(pthread_key_t HDR pthread_key_t.h) add_header(pthread_mutex_t HDR pthread_mutex_t.h DEPENDS .__futex_word .__mutex_type) add_header(pthread_mutexattr_t HDR pthread_mutexattr_t.h) add_header(pthread_once_t HDR pthread_once_t.h DEPENDS .__futex_word) +add_header(pthread_rwlockattr_t HDR pthread_rwlockattr_t.h) add_header(pthread_t HDR pthread_t.h DEPENDS .__thread_type) add_header(rlim_t HDR rlim_t.h) add_header(time_t HDR time_t.h) diff --git a/libc/include/llvm-libc-types/pthread_rwlockattr_t.h b/libc/include/llvm-libc-types/pthread_rwlockattr_t.h new file mode 100644 index 000000000000..a63de4f7b438 --- /dev/null +++ b/libc/include/llvm-libc-types/pthread_rwlockattr_t.h @@ -0,0 +1,15 @@ +//===-- Definition of pthread_rwlockattr_t type ---------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_LIBC_TYPES_PTHREAD_RWLOCKATTR_T_H +#define LLVM_LIBC_TYPES_PTHREAD_RWLOCKATTR_T_H + +typedef struct { + int pshared; +} pthread_rwlockattr_t; + +#endif // LLVM_LIBC_TYPES_PTHREAD_RWLOCKATTR_T_H diff --git a/libc/spec/posix.td b/libc/spec/posix.td index 0c88dbd848a3..d428d54e32a3 100644 --- a/libc/spec/posix.td +++ b/libc/spec/posix.td @@ -110,6 +110,10 @@ def POSIX : StandardSpec<"POSIX"> { PtrType PThreadCondAttrTPtr = PtrType; ConstType ConstRestrictedPThreadCondAttrTPtr = ConstType>; + NamedType PThreadRWLockAttrTType = NamedType<"pthread_rwlockattr_t">; + PtrType PThreadRWLockAttrTPtr = PtrType; + ConstType ConstPThreadRWLockAttrTPtr = ConstType; + NamedType PThreadMutexAttrTType = NamedType<"pthread_mutexattr_t">; PtrType PThreadMutexAttrTPtr = PtrType; RestrictedPtrType RestrictedPThreadMutexAttrTPtr = RestrictedPtrType; @@ -993,6 +997,7 @@ def POSIX : StandardSpec<"POSIX"> { PThreadMutexTType, PThreadOnceCallback, PThreadOnceT, + PThreadRWLockAttrTType, PThreadStartT, PThreadTSSDtorT, PThreadTType, @@ -1219,6 +1224,26 @@ def POSIX : StandardSpec<"POSIX"> { RetValSpec, [ArgSpec, ArgSpec] >, + FunctionSpec< + "pthread_rwlockattr_destroy", + RetValSpec, + [ArgSpec] + >, + FunctionSpec< + "pthread_rwlockattr_getpshared", + RetValSpec, + [ArgSpec, ArgSpec] + >, + FunctionSpec< + "pthread_rwlockattr_init", + RetValSpec, + [ArgSpec] + >, + FunctionSpec< + "pthread_rwlockattr_setpshared", + RetValSpec, + [ArgSpec, ArgSpec] + >, ] >; @@ -1575,6 +1600,7 @@ def POSIX : StandardSpec<"POSIX"> { PThreadMutexAttrTType, PThreadMutexTType, PThreadOnceT, + PThreadRWLockAttrTType, PThreadTType, PidT, SSizeTType, diff --git a/libc/src/pthread/CMakeLists.txt b/libc/src/pthread/CMakeLists.txt index 3d6cf6dde010..c57475c9114f 100644 --- a/libc/src/pthread/CMakeLists.txt +++ b/libc/src/pthread/CMakeLists.txt @@ -460,6 +460,47 @@ add_entrypoint_object( libc.src.__support.threads.thread ) +add_entrypoint_object( + pthread_rwlockattr_destroy + SRCS + pthread_rwlockattr_destroy.cpp + HDRS + pthread_rwlockattr_destroy.h + DEPENDS + libc.include.pthread +) + +add_entrypoint_object( + pthread_rwlockattr_getpshared + SRCS + pthread_rwlockattr_getpshared.cpp + HDRS + pthread_rwlockattr_getpshared.h + DEPENDS + libc.include.pthread +) + +add_entrypoint_object( + pthread_rwlockattr_init + SRCS + pthread_rwlockattr_init.cpp + HDRS + pthread_rwlockattr_init.h + DEPENDS + libc.include.pthread +) + +add_entrypoint_object( + pthread_rwlockattr_setpshared + SRCS + pthread_rwlockattr_setpshared.cpp + HDRS + pthread_rwlockattr_setpshared.h + DEPENDS + libc.include.pthread + libc.include.errno +) + add_entrypoint_object( pthread_once SRCS diff --git a/libc/src/pthread/pthread_rwlockattr_destroy.cpp b/libc/src/pthread/pthread_rwlockattr_destroy.cpp new file mode 100644 index 000000000000..e3ca75112f0e --- /dev/null +++ b/libc/src/pthread/pthread_rwlockattr_destroy.cpp @@ -0,0 +1,24 @@ +//===-- Implementation of the pthread_rwlockattr_destroy ------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "pthread_rwlockattr_destroy.h" + +#include "src/__support/common.h" + +#include // pthread_rwlockattr_t + +namespace LIBC_NAMESPACE { + +LLVM_LIBC_FUNCTION(int, pthread_rwlockattr_destroy, + (pthread_rwlockattr_t * attr [[gnu::unused]])) { + // Initializing a pthread_rwlockattr_t acquires no resources, so this is a + // no-op. + return 0; +} + +} // namespace LIBC_NAMESPACE diff --git a/libc/src/pthread/pthread_rwlockattr_destroy.h b/libc/src/pthread/pthread_rwlockattr_destroy.h new file mode 100644 index 000000000000..5904d6b00418 --- /dev/null +++ b/libc/src/pthread/pthread_rwlockattr_destroy.h @@ -0,0 +1,20 @@ +//===-- Implementation header for pthread_rwlockattr_destroy ----*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_PTHREAD_PTHREAD_RWLOCKATTR_DESTROY_H +#define LLVM_LIBC_SRC_PTHREAD_PTHREAD_RWLOCKATTR_DESTROY_H + +#include + +namespace LIBC_NAMESPACE { + +int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr); + +} // namespace LIBC_NAMESPACE + +#endif // LLVM_LIBC_SRC_PTHREAD_PTHREAD_RWLOCKATTR_DESTROY_H diff --git a/libc/src/pthread/pthread_rwlockattr_getpshared.cpp b/libc/src/pthread/pthread_rwlockattr_getpshared.cpp new file mode 100644 index 000000000000..0dad230a2bde --- /dev/null +++ b/libc/src/pthread/pthread_rwlockattr_getpshared.cpp @@ -0,0 +1,23 @@ +//===-- Implementation of the pthread_rwlockattr_getpshared ---------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "pthread_rwlockattr_getpshared.h" + +#include "src/__support/common.h" + +#include // pthread_rwlockattr_t + +namespace LIBC_NAMESPACE { + +LLVM_LIBC_FUNCTION(int, pthread_rwlockattr_getpshared, + (const pthread_rwlockattr_t *attr, int *pshared)) { + *pshared = attr->pshared; + return 0; +} + +} // namespace LIBC_NAMESPACE diff --git a/libc/src/pthread/pthread_rwlockattr_getpshared.h b/libc/src/pthread/pthread_rwlockattr_getpshared.h new file mode 100644 index 000000000000..64843e59aae6 --- /dev/null +++ b/libc/src/pthread/pthread_rwlockattr_getpshared.h @@ -0,0 +1,21 @@ +//===-- Implementation header for pthread_rwlockattr_getpshared -*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_PTHREAD_PTHREAD_RWLOCKATTR_GETPSHARED_H +#define LLVM_LIBC_SRC_PTHREAD_PTHREAD_RWLOCKATTR_GETPSHARED_H + +#include + +namespace LIBC_NAMESPACE { + +int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *attr, + int *pshared); + +} // namespace LIBC_NAMESPACE + +#endif // LLVM_LIBC_SRC_PTHREAD_PTHREAD_RWLOCKATTR_GETPSHARED_H diff --git a/libc/src/pthread/pthread_rwlockattr_init.cpp b/libc/src/pthread/pthread_rwlockattr_init.cpp new file mode 100644 index 000000000000..7971f1714db4 --- /dev/null +++ b/libc/src/pthread/pthread_rwlockattr_init.cpp @@ -0,0 +1,23 @@ +//===-- Implementation of the pthread_rwlockattr_init ---------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "pthread_rwlockattr_init.h" + +#include "src/__support/common.h" + +#include // pthread_rwlockattr_t, PTHREAD_PROCESS_PRIVATE + +namespace LIBC_NAMESPACE { + +LLVM_LIBC_FUNCTION(int, pthread_rwlockattr_init, + (pthread_rwlockattr_t * attr)) { + attr->pshared = PTHREAD_PROCESS_PRIVATE; + return 0; +} + +} // namespace LIBC_NAMESPACE diff --git a/libc/src/pthread/pthread_rwlockattr_init.h b/libc/src/pthread/pthread_rwlockattr_init.h new file mode 100644 index 000000000000..30ae499fb65d --- /dev/null +++ b/libc/src/pthread/pthread_rwlockattr_init.h @@ -0,0 +1,20 @@ +//===-- Implementation header for pthread_rwlockattr_init ----*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_PTHREAD_PTHREAD_RWLOCKATTR_INIT_H +#define LLVM_LIBC_SRC_PTHREAD_PTHREAD_RWLOCKATTR_INIT_H + +#include + +namespace LIBC_NAMESPACE { + +int pthread_rwlockattr_init(pthread_rwlockattr_t *attr); + +} // namespace LIBC_NAMESPACE + +#endif // LLVM_LIBC_SRC_PTHREAD_PTHREAD_RWLOCKATTR_INIT_H diff --git a/libc/src/pthread/pthread_rwlockattr_setpshared.cpp b/libc/src/pthread/pthread_rwlockattr_setpshared.cpp new file mode 100644 index 000000000000..6bcba7c1b493 --- /dev/null +++ b/libc/src/pthread/pthread_rwlockattr_setpshared.cpp @@ -0,0 +1,27 @@ +//===-- Implementation of the pthread_rwlockattr_setpshared ---------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "pthread_rwlockattr_setpshared.h" + +#include "src/__support/common.h" + +#include // EINVAL +#include // pthread_rwlockattr_t, PTHREAD_PROCESS_SHARED, PTHREAD_PROCESS_PRIVATE + +namespace LIBC_NAMESPACE { + +LLVM_LIBC_FUNCTION(int, pthread_rwlockattr_setpshared, + (pthread_rwlockattr_t * attr, int pshared)) { + if (pshared != PTHREAD_PROCESS_SHARED && pshared != PTHREAD_PROCESS_PRIVATE) + return EINVAL; + + attr->pshared = pshared; + return 0; +} + +} // namespace LIBC_NAMESPACE diff --git a/libc/src/pthread/pthread_rwlockattr_setpshared.h b/libc/src/pthread/pthread_rwlockattr_setpshared.h new file mode 100644 index 000000000000..393c07d1eecb --- /dev/null +++ b/libc/src/pthread/pthread_rwlockattr_setpshared.h @@ -0,0 +1,20 @@ +//===-- Implementation header for pthread_rwlockattr_setpshared -*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_PTHREAD_PTHREAD_RWLOCKATTR_SETPSHARED_H +#define LLVM_LIBC_SRC_PTHREAD_PTHREAD_RWLOCKATTR_SETPSHARED_H + +#include + +namespace LIBC_NAMESPACE { + +int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *attr, int pshared); + +} // namespace LIBC_NAMESPACE + +#endif // LLVM_LIBC_SRC_PTHREAD_PTHREAD_RWLOCKATTR_SETPSHARED_H diff --git a/libc/test/src/pthread/CMakeLists.txt b/libc/test/src/pthread/CMakeLists.txt index 4d01b667f12c..ea75e65f57c9 100644 --- a/libc/test/src/pthread/CMakeLists.txt +++ b/libc/test/src/pthread/CMakeLists.txt @@ -56,4 +56,19 @@ add_libc_unittest( libc.src.pthread.pthread_condattr_init libc.src.pthread.pthread_condattr_setclock libc.src.pthread.pthread_condattr_setpshared - ) +) + +add_libc_unittest( + pthread_rwlockattr_test + SUITE + libc_pthread_unittests + SRCS + pthread_rwlockattr_test.cpp + DEPENDS + libc.include.errno + libc.include.pthread + libc.src.pthread.pthread_rwlockattr_destroy + libc.src.pthread.pthread_rwlockattr_getpshared + libc.src.pthread.pthread_rwlockattr_init + libc.src.pthread.pthread_rwlockattr_setpshared +) diff --git a/libc/test/src/pthread/pthread_rwlockattr_test.cpp b/libc/test/src/pthread/pthread_rwlockattr_test.cpp new file mode 100644 index 000000000000..6e5ae70df734 --- /dev/null +++ b/libc/test/src/pthread/pthread_rwlockattr_test.cpp @@ -0,0 +1,64 @@ +//===-- Unittests for pthread_rwlockattr_t --------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "include/llvm-libc-macros/generic-error-number-macros.h" // EINVAL +#include "src/pthread/pthread_rwlockattr_destroy.h" +#include "src/pthread/pthread_rwlockattr_getpshared.h" +#include "src/pthread/pthread_rwlockattr_init.h" +#include "src/pthread/pthread_rwlockattr_setpshared.h" +#include "test/UnitTest/Test.h" + +// TODO: https://github.com/llvm/llvm-project/issues/88997 +#include // PTHREAD_PROCESS_PRIVATE, PTHREAD_PROCESS_SHARED + +TEST(LlvmLibcPThreadRWLockAttrTest, InitAndDestroy) { + pthread_rwlockattr_t attr; + ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_init(&attr), 0); + ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_destroy(&attr), 0); +} + +TEST(LlvmLibcPThreadRWLockAttrTest, GetDefaultValues) { + pthread_rwlockattr_t attr; + + // Invalid value. + int pshared = 42; + + ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_init(&attr), 0); + ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_getpshared(&attr, &pshared), 0); + ASSERT_EQ(pshared, PTHREAD_PROCESS_PRIVATE); + ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_destroy(&attr), 0); +} + +TEST(LlvmLibcPThreadRWLockAttrTest, SetGoodValues) { + pthread_rwlockattr_t attr; + + // Invalid value. + int pshared = 42; + + ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_init(&attr), 0); + ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_setpshared( + &attr, PTHREAD_PROCESS_SHARED), + 0); + ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_getpshared(&attr, &pshared), 0); + ASSERT_EQ(pshared, PTHREAD_PROCESS_SHARED); + ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_destroy(&attr), 0); +} + +TEST(LlvmLibcPThreadRWLockAttrTest, SetBadValues) { + pthread_rwlockattr_t attr; + + // Invalid value. + int pshared = 42; + + ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_init(&attr), 0); + ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_setpshared(&attr, pshared), + EINVAL); + ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_getpshared(&attr, &pshared), 0); + ASSERT_EQ(pshared, PTHREAD_PROCESS_PRIVATE); + ASSERT_EQ(LIBC_NAMESPACE::pthread_rwlockattr_destroy(&attr), 0); +} -- GitLab From 6b1b4c1c54d4276409c336eaf6d47b3bc04035c3 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Mon, 22 Apr 2024 12:04:15 -0700 Subject: [PATCH 024/732] [RISCV][clang] Don't enable -mrelax-all for -O0 on RISC-V (#88538) -O0 implies -mrelax-all as an assembler compile time optimization. -mrelax-all allows the assembler to complete layout in 2 passes instead of doing iterative branch relaxation. Jump offsets larger than +/-1MiB require an indirect jump on RISC-V. This can't be done by the assembler, so we use a branch relaxation MIR pass and use register scavenging to find a free register. The conditional branch offsets for RISC-V are also somewhat small so we support MC layer branch relaxation to make life easier for assembly programmers. This may also cover up bugs in our function size estimation in MachineIR. Enabling -mrelax-all causes the MC layer relaxation to agressively relax branches. This increases code size and can create cases where we need an indirect jump, but we can't create one. This leads to linker failures. The easiest way to avoid this is to not default to -mrelax-all for -O0 and sacrifice the compile time optimization. That's what this patch does. Fixes #87127 --- clang/lib/Driver/ToolChains/Clang.cpp | 10 ++++++++++ clang/test/Driver/integrated-as.c | 8 +++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index f8a81ee8ab56..5894a48e0e37 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -847,6 +847,16 @@ static bool UseRelaxAll(Compilation &C, const ArgList &Args) { if (Arg *A = Args.getLastArg(options::OPT_O_Group)) RelaxDefault = A->getOption().matches(options::OPT_O0); + // RISC-V requires an indirect jump for offsets larger than 1MiB. This cannot + // be done by assembler branch relaxation as it needs a free temporary + // register. Because of this, branch relaxation is handled by a MachineIR + // pass before the assembler. Forcing assembler branch relaxation for -O0 + // makes the MachineIR branch relaxation inaccurate and it will miss cases + // where an indirect branch is necessary. To avoid this issue we are + // sacrificing the compile time improvement of using -mrelax-all for -O0. + if (C.getDefaultToolChain().getTriple().isRISCV()) + RelaxDefault = false; + if (RelaxDefault) { RelaxDefault = false; for (const auto &Act : C.getActions()) { diff --git a/clang/test/Driver/integrated-as.c b/clang/test/Driver/integrated-as.c index d7658fdfd633..e78fde873cf4 100644 --- a/clang/test/Driver/integrated-as.c +++ b/clang/test/Driver/integrated-as.c @@ -1,10 +1,16 @@ // XFAIL: target={{.*}}-aix{{.*}} -// RUN: %clang -### -c -save-temps -integrated-as %s 2>&1 | FileCheck %s +// RUN: %clang -### -c -save-temps -integrated-as --target=x86_64 %s 2>&1 | FileCheck %s // CHECK: cc1as // CHECK: -mrelax-all +// RISC-V does not enable -mrelax-all +// RUN: %clang -### -c -save-temps -integrated-as --target=riscv64 %s 2>&1 | FileCheck %s -check-prefix=RISCV-RELAX + +// RISCV-RELAX: cc1as +// RISCV-RELAX-NOT: -mrelax-all + // RUN: %clang -### -fintegrated-as -c -save-temps %s 2>&1 | FileCheck %s -check-prefix FIAS // FIAS: cc1as -- GitLab From a6f1b3a4c79209b01733bc1857c87b2abe0b4ecf Mon Sep 17 00:00:00 2001 From: Joseph Huber Date: Mon, 22 Apr 2024 14:10:12 -0500 Subject: [PATCH 025/732] [Offload] Fix per-target install directory (#89645) Summary: The move from `openmp` to `offload` did not preserve the per-target runtime directory installation. This is important because this per-target directory is always included first and is likely the de-facto way to handle these going forward. Without this installation, old installations of the library will be linked against first. --- offload/CMakeLists.txt | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/offload/CMakeLists.txt b/offload/CMakeLists.txt index b23ffdcbd5aa..abc8baa0805f 100644 --- a/offload/CMakeLists.txt +++ b/offload/CMakeLists.txt @@ -39,8 +39,21 @@ if (OPENMP_ENABLE_LIBOMPTARGET) endif() endif() -# TODO: Leftover from the move, could probably be just LLVM_LIBDIR_SUFFIX everywhere. -set(OFFLOAD_INSTALL_LIBDIR "lib${LLVM_LIBDIR_SUFFIX}") +if(OPENMP_STANDALONE_BUILD) + set(OFFLOAD_LIBDIR_SUFFIX "" CACHE STRING + "Suffix of lib installation directory, e.g. 64 => lib64") + set(OFFLOAD_INSTALL_LIBDIR "lib${OFFLOAD_LIBDIR_SUFFIX}" CACHE STRING + "Path where built offload libraries should be installed.") +else() + # When building in tree we install the runtime according to the LLVM settings. + if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE) + set(OFFLOAD_INSTALL_LIBDIR lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE} CACHE STRING + "Path where built offload libraries should be installed.") + else() + set(OFFLOAD_INSTALL_LIBDIR "lib${LLVM_LIBDIR_SUFFIX}" CACHE STRING + "Path where built offload libraries should be installed.") + endif() +endif() set(LLVM_COMMON_CMAKE_UTILS ${CMAKE_CURRENT_SOURCE_DIR}/../cmake) -- GitLab From 89c95effe82c09b9a42408f4823409331f8fa266 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 22 Apr 2024 12:35:04 -0700 Subject: [PATCH 026/732] [llvm-readobj] Remove --raw-relr https://reviews.llvm.org/D47919 dumped RELR relocations as `R_*_RELATIVE` and added --raw-relr (not in GNU) for testing purposes (more readable than `llvm-readelf -x .relr.dyn`). The option is obsolete after `llvm-readelf -r` output gets improved (#89162). Since --raw-relr never seems to get more adoption. Let's remove it to avoid some complexity. Pull Request: https://github.com/llvm/llvm-project/pull/89426 --- llvm/docs/CommandGuide/llvm-readelf.rst | 4 -- llvm/docs/CommandGuide/llvm-readobj.rst | 4 -- llvm/docs/ReleaseNotes.rst | 4 ++ .../tools/llvm-readobj/ELF/relr-relocs.test | 49 +------------ llvm/tools/llvm-readobj/ELFDumper.cpp | 68 ++++--------------- llvm/tools/llvm-readobj/Opts.td | 1 - llvm/tools/llvm-readobj/llvm-readobj.cpp | 2 - llvm/tools/llvm-readobj/llvm-readobj.h | 1 - 8 files changed, 21 insertions(+), 112 deletions(-) diff --git a/llvm/docs/CommandGuide/llvm-readelf.rst b/llvm/docs/CommandGuide/llvm-readelf.rst index 675628fdda45..284c3aa470a6 100644 --- a/llvm/docs/CommandGuide/llvm-readelf.rst +++ b/llvm/docs/CommandGuide/llvm-readelf.rst @@ -152,10 +152,6 @@ OPTIONS Display the program headers. -.. option:: --raw-relr - - Do not decode relocations in RELR relocation sections when displaying them. - .. option:: --relocations, --relocs, -r Display the relocation entries in the file. diff --git a/llvm/docs/CommandGuide/llvm-readobj.rst b/llvm/docs/CommandGuide/llvm-readobj.rst index ca7fb253f00a..8bd29eafbbfc 100644 --- a/llvm/docs/CommandGuide/llvm-readobj.rst +++ b/llvm/docs/CommandGuide/llvm-readobj.rst @@ -255,10 +255,6 @@ The following options are implemented only for the ELF file format. Display the program headers. -.. option:: --raw-relr - - Do not decode relocations in RELR relocation sections when displaying them. - .. option:: --section-mapping Display the section to segment mapping. diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst index 76ef6ceb9407..580dc512d969 100644 --- a/llvm/docs/ReleaseNotes.rst +++ b/llvm/docs/ReleaseNotes.rst @@ -198,6 +198,10 @@ Changes to the LLVM tools documentation for SPGO `_. +* llvm-readelf's ``-r`` output for RELR has been improved. + (`#89162 `_) + ``--raw-relr`` has been removed. + Changes to LLDB --------------------------------- diff --git a/llvm/test/tools/llvm-readobj/ELF/relr-relocs.test b/llvm/test/tools/llvm-readobj/ELF/relr-relocs.test index 9b59f991c051..c22239900bcf 100644 --- a/llvm/test/tools/llvm-readobj/ELF/relr-relocs.test +++ b/llvm/test/tools/llvm-readobj/ELF/relr-relocs.test @@ -1,16 +1,6 @@ ## This is a test to test how SHT_RELR sections are dumped. # RUN: yaml2obj --docnum=1 %s -o %t1 -# RUN: llvm-readobj --relocations --raw-relr %t1 \ -# RUN: | FileCheck --check-prefix=RAW-LLVM1 %s -# RAW-LLVM1: Section (1) .relr.dyn { -# RAW-LLVM1-NEXT: 0x10D60 -# RAW-LLVM1-NEXT: 0x103 -# RAW-LLVM1-NEXT: 0x20000 -# RAW-LLVM1-NEXT: 0xF0501 -# RAW-LLVM1-NEXT: 0xA700550400009 -# RAW-LLVM1-NEXT: } - # RUN: llvm-readobj --relocations %t1 | \ # RUN: FileCheck --match-full-lines --check-prefix=LLVM1 %s @@ -38,15 +28,6 @@ # LLVM1-NEXT: 0x20390 R_X86_64_RELATIVE - # LLVM1-NEXT: } -# RUN: llvm-readelf --relocations --raw-relr %t1 \ -# RUN: | FileCheck --check-prefix=RAW-GNU1 %s -# RAW-GNU1: Relocation section '.relr.dyn' at offset 0x40 contains 5 entries: -# RAW-GNU1: 0000000000010d60 -# RAW-GNU1-NEXT: 0000000000000103 -# RAW-GNU1-NEXT: 0000000000020000 -# RAW-GNU1-NEXT: 00000000000f0501 -# RAW-GNU1-NEXT: 000a700550400009 - # RUN: llvm-readelf --relocations %t1 | FileCheck --check-prefix=GNU1 --match-full-lines --strict-whitespace %s # GNU1:Relocation section '.relr.dyn' at offset 0x40 contains 21 entries: # GNU1-NEXT:Index: Entry Address Symbolic Address @@ -107,16 +88,6 @@ Symbols: Value: 0x20210 # RUN: yaml2obj --docnum=2 %s -o %t2 -# RUN: llvm-readobj --relocations --raw-relr %t2 | \ -# RUN: FileCheck --check-prefix=RAW-LLVM2 %s -# RAW-LLVM2: Section (1) .relr.dyn { -# RAW-LLVM2-NEXT: 0x10D60 -# RAW-LLVM2-NEXT: 0x103 -# RAW-LLVM2-NEXT: 0x20000 -# RAW-LLVM2-NEXT: 0xF0501 -# RAW-LLVM2-NEXT: 0x50400009 -# RAW-LLVM2-NEXT: } - # RUN: llvm-readobj --relocations %t2 | \ # RUN: FileCheck --match-full-lines --check-prefix=LLVM2 %s @@ -137,15 +108,6 @@ Symbols: # LLVM2-NEXT: 0x200F4 R_386_RELATIVE - # LLVM2-NEXT: } -# RUN: llvm-readelf --relocations --raw-relr %t2 | \ -# RUN: FileCheck --check-prefix=RAW-GNU2 %s -# RAW-GNU2: Relocation section '.relr.dyn' at offset 0x34 contains 5 entries: -# RAW-GNU2: 00010d60 -# RAW-GNU2-NEXT: 00000103 -# RAW-GNU2-NEXT: 00020000 -# RAW-GNU2-NEXT: 000f0501 -# RAW-GNU2-NEXT: 50400009 - # RUN: llvm-readelf --relocations %t2 | FileCheck --check-prefix=GNU2 --match-full-lines --strict-whitespace %s # GNU2:Relocation section '.relr.dyn' at offset 0x34 contains 14 entries: # GNU2-NEXT:Index: Entry Address Symbolic Address @@ -232,21 +194,14 @@ Symbols: ## only relative relocations and do not have an associated symbol table, like other ## relocation sections. -## Case A: check we do not report warnings when the sh_link field is set to an arbitrary value -## and the --relocations option is requested. +## Check we do not report warnings when the sh_link field is set to an arbitrary value +## and the --relocations option is requested. # RUN: yaml2obj --docnum=2 -DLINK=0xff %s -o %t2.has.link # RUN: llvm-readobj --relocations %t2.has.link 2>&1 | \ # RUN: FileCheck -DFILE=%t2.has.link --check-prefix=LLVM2 %s --implicit-check-not=warning: # RUN: llvm-readelf --relocations %t2.has.link 2>&1 | \ # RUN: FileCheck -DFILE=%t2.has.link --check-prefix=GNU2 %s --implicit-check-not=warning: -## Case B: check we do not report warnings when the sh_link field is set to an arbitrary value -## and --relocations and --raw-relr options are requested. -# RUN: llvm-readobj --relocations --raw-relr %t2.has.link | \ -# RUN: FileCheck -DFILE=%t2.has.link --check-prefix=RAW-LLVM2 %s -# RUN: llvm-readelf --relocations --raw-relr %t2.has.link 2>&1 | \ -# RUN: FileCheck -DFILE=%t2.has.link --check-prefix=RAW-GNU2 %s - ## .symtab is invalid. Check we report a warning and print entries without symbolization. # RUN: yaml2obj --docnum=3 -DENTSIZE=1 %s -o %t3.err1 # RUN: llvm-readelf -r %t3.err1 2>&1 | FileCheck -DFILE=%t3.err1 --check-prefixes=GNU3,GNU3-ERR1 --match-full-lines %s diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index f145653ac743..a752cc401529 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -285,7 +285,6 @@ protected: virtual void printRelRelaReloc(const Relocation &R, const RelSymbol &RelSym) = 0; - virtual void printRelrReloc(const Elf_Relr &R) = 0; virtual void printDynamicRelocHeader(unsigned Type, StringRef Name, const DynRegionInfo &Reg) {} void printReloc(const Relocation &R, unsigned RelIndex, @@ -294,11 +293,10 @@ protected: void printDynamicRelocationsHelper(); void printRelocationsHelper(const Elf_Shdr &Sec); void forEachRelocationDo( - const Elf_Shdr &Sec, bool RawRelr, + const Elf_Shdr &Sec, llvm::function_ref &, unsigned, const Elf_Shdr &, const Elf_Shdr *)> - RelRelaFn, - llvm::function_ref RelrFn); + RelRelaFn); virtual void printSymtabMessage(const Elf_Shdr *Symtab, size_t Offset, bool NonVisibilityBitsUsed, @@ -669,7 +667,6 @@ private: DataRegion ShndxTable, StringRef StrTable, uint32_t Bucket); void printRelr(const Elf_Shdr &Sec); - void printRelrReloc(const Elf_Relr &R) override; void printRelRelaReloc(const Relocation &R, const RelSymbol &RelSym) override; void printSymbol(const Elf_Sym &Symbol, unsigned SymIndex, @@ -734,7 +731,6 @@ public: bool IsGnu) const override; private: - void printRelrReloc(const Elf_Relr &R) override; void printRelRelaReloc(const Relocation &R, const RelSymbol &RelSym) override; @@ -3800,11 +3796,6 @@ template void GNUELFDumper::printGroupSections() { OS << "There are no section groups in this file.\n"; } -template -void GNUELFDumper::printRelrReloc(const Elf_Relr &R) { - OS << to_string(format_hex_no_prefix(R, ELFT::Is64Bits ? 16 : 8)) << "\n"; -} - template void GNUELFDumper::printRelRelaReloc(const Relocation &R, const RelSymbol &RelSym) { @@ -3851,22 +3842,11 @@ template static void printRelocHeaderFields(formatted_raw_ostream &OS, unsigned SType, const typename ELFT::Ehdr &EHeader) { bool IsRela = SType == ELF::SHT_RELA || SType == ELF::SHT_ANDROID_RELA; - bool IsRelr = - SType == ELF::SHT_RELR || SType == ELF::SHT_ANDROID_RELR || - (EHeader.e_machine == EM_AARCH64 && SType == ELF::SHT_AARCH64_AUTH_RELR); - if (ELFT::Is64Bits) - OS << " "; - else - OS << " "; - if (IsRelr && opts::RawRelr) - OS << "Data "; - else - OS << "Offset"; if (ELFT::Is64Bits) - OS << " Info Type" - << " Symbol's Value Symbol's Name"; + OS << " Offset Info Type Symbol's " + "Value Symbol's Name"; else - OS << " Info Type Sym. Value Symbol's Name"; + OS << " Offset Info Type Sym. Value Symbol's Name"; if (IsRela) OS << " + Addend"; OS << "\n"; @@ -3894,10 +3874,10 @@ static bool isRelocationSec(const typename ELFT::Shdr &Sec, template void GNUELFDumper::printRelocations() { auto PrintAsRelr = [&](const Elf_Shdr &Sec) { - return !opts::RawRelr && (Sec.sh_type == ELF::SHT_RELR || - Sec.sh_type == ELF::SHT_ANDROID_RELR || - (this->Obj.getHeader().e_machine == EM_AARCH64 && - Sec.sh_type == ELF::SHT_AARCH64_AUTH_RELR)); + return Sec.sh_type == ELF::SHT_RELR || + Sec.sh_type == ELF::SHT_ANDROID_RELR || + (this->Obj.getHeader().e_machine == EM_AARCH64 && + Sec.sh_type == ELF::SHT_AARCH64_AUTH_RELR); }; auto GetEntriesNum = [&](const Elf_Shdr &Sec) -> Expected { // Android's packed relocation section needs to be unpacked first @@ -4902,10 +4882,8 @@ void ELFDumper::printDynamicReloc(const Relocation &R) { template void ELFDumper::printRelocationsHelper(const Elf_Shdr &Sec) { this->forEachRelocationDo( - Sec, opts::RawRelr, - [&](const Relocation &R, unsigned Ndx, const Elf_Shdr &Sec, - const Elf_Shdr *SymTab) { printReloc(R, Ndx, Sec, SymTab); }, - [&](const Elf_Relr &R) { printRelrReloc(R); }); + Sec, [&](const Relocation &R, unsigned Ndx, const Elf_Shdr &Sec, + const Elf_Shdr *SymTab) { printReloc(R, Ndx, Sec, SymTab); }); } template void ELFDumper::printDynamicRelocationsHelper() { @@ -6371,11 +6349,10 @@ void ELFDumper::printDependentLibsHelper( template void ELFDumper::forEachRelocationDo( - const Elf_Shdr &Sec, bool RawRelr, + const Elf_Shdr &Sec, llvm::function_ref &, unsigned, const Elf_Shdr &, const Elf_Shdr *)> - RelRelaFn, - llvm::function_ref RelrFn) { + RelRelaFn) { auto Warn = [&](Error &&E, const Twine &Prefix = "unable to read relocations from") { this->reportUniqueWarning(Prefix + " " + describe(Sec) + ": " + @@ -6427,11 +6404,6 @@ void ELFDumper::forEachRelocationDo( Warn(RangeOrErr.takeError()); break; } - if (RawRelr) { - for (const Elf_Relr &R : *RangeOrErr) - RelrFn(R); - break; - } for (const Elf_Rel &R : Obj.decode_relrs(*RangeOrErr)) RelRelaFn(Relocation(R, IsMips64EL), RelNdx++, Sec, @@ -6741,9 +6713,8 @@ void ELFDumper::printRelocatableStackSizes( DataExtractor Data(Contents, Obj.isLE(), sizeof(Elf_Addr)); forEachRelocationDo( - *RelocSec, /*RawRelr=*/false, - [&](const Relocation &R, unsigned Ndx, const Elf_Shdr &Sec, - const Elf_Shdr *SymTab) { + *RelocSec, [&](const Relocation &R, unsigned Ndx, + const Elf_Shdr &Sec, const Elf_Shdr *SymTab) { if (!IsSupportedFn || !IsSupportedFn(R.Type)) { reportUniqueWarning( describe(*RelocSec) + @@ -6754,10 +6725,6 @@ void ELFDumper::printRelocatableStackSizes( this->printStackSize(R, *RelocSec, Ndx, SymTab, FunctionSec, *StackSizesELFSec, Resolver, Data); - }, - [](const Elf_Relr &) { - llvm_unreachable("can't get here, because we only support " - "SHT_REL/SHT_RELA sections"); }); } } @@ -7147,11 +7114,6 @@ template void LLVMELFDumper::printRelocations() { } } -template -void LLVMELFDumper::printRelrReloc(const Elf_Relr &R) { - W.startLine() << W.hex(R) << "\n"; -} - template void LLVMELFDumper::printExpandedRelRelaReloc(const Relocation &R, StringRef SymbolName, diff --git a/llvm/tools/llvm-readobj/Opts.td b/llvm/tools/llvm-readobj/Opts.td index 1e9cde6b2e87..7d574d875d22 100644 --- a/llvm/tools/llvm-readobj/Opts.td +++ b/llvm/tools/llvm-readobj/Opts.td @@ -62,7 +62,6 @@ def memtag : FF<"memtag", "Display memory tagging metadata (modes, Android notes def needed_libs : FF<"needed-libs", "Display the needed libraries">, Group; def notes : FF<"notes", "Display notes">, Group; def program_headers : FF<"program-headers", "Display program headers">, Group; -def raw_relr : FF<"raw-relr", "Do not decode relocations in SHT_RELR section, display raw contents">, Group; def version_info : FF<"version-info", "Display version sections">, Group; // Mach-O specific options. diff --git a/llvm/tools/llvm-readobj/llvm-readobj.cpp b/llvm/tools/llvm-readobj/llvm-readobj.cpp index a0b576566016..9ac324cc672f 100644 --- a/llvm/tools/llvm-readobj/llvm-readobj.cpp +++ b/llvm/tools/llvm-readobj/llvm-readobj.cpp @@ -134,7 +134,6 @@ static bool Memtag; static bool NeededLibraries; static bool Notes; static bool ProgramHeaders; -bool RawRelr; static bool SectionGroups; static bool VersionInfo; @@ -273,7 +272,6 @@ static void parseOptions(const opt::InputArgList &Args) { opts::Notes = Args.hasArg(OPT_notes); opts::PrettyPrint = Args.hasArg(OPT_pretty_print); opts::ProgramHeaders = Args.hasArg(OPT_program_headers); - opts::RawRelr = Args.hasArg(OPT_raw_relr); opts::SectionGroups = Args.hasArg(OPT_section_groups); if (Arg *A = Args.getLastArg(OPT_sort_symbols_EQ)) { std::string SortKeysString = A->getValue(); diff --git a/llvm/tools/llvm-readobj/llvm-readobj.h b/llvm/tools/llvm-readobj/llvm-readobj.h index 532e43d4e16b..e4ee2c1396b2 100644 --- a/llvm/tools/llvm-readobj/llvm-readobj.h +++ b/llvm/tools/llvm-readobj/llvm-readobj.h @@ -38,7 +38,6 @@ extern bool SectionRelocations; extern bool SectionSymbols; extern bool SectionData; extern bool ExpandRelocs; -extern bool RawRelr; extern bool CodeViewSubsectionBytes; extern bool Demangle; enum OutputStyleTy { LLVM, GNU, JSON, UNKNOWN }; -- GitLab From 40137ff0d81be80e4900c17c57b1f66c53ddf2f9 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Mon, 22 Apr 2024 14:41:11 -0500 Subject: [PATCH 027/732] [Frontend][OpenMP] Refactor getLeafConstructs, add getCompoundConstruct (#87247) Emit a special leaf construct table in DirectiveEmitter.cpp, which will allow both decomposition of a construct into leafs, and composition of constituent constructs into a single compound construct (if possible). The function `getLeafConstructs` is no longer auto-generated, but implemented in OMP.cpp. The table contains a row for each directive, and each row has the following format `dir_id, num_leafs, leaf1, leaf2, ..., leafN, -1, ...` The rows are sorted lexicographically with respect to the leaf constructs. This allows a binary search for the row corresponding to the given list of leafs. There is an auxiliary table that for each directive contains the index of the row corresponding to that directive. Looking up leaf constructs for a directive `dir_id` is of constant time, and and consists of two lookups: `LeafTable[Auxiliary[dir_id]]`. Finding a compound directive given the set of leafs is of time O(logn), and is roughly represented by `row = binary_search(LeafTable); return row[0]`. The functions `getLeafConstructs` and `getCompoundConstruct` use these lookup methods internally. --- llvm/include/llvm/Frontend/OpenMP/OMP.h | 7 + llvm/lib/Frontend/OpenMP/OMP.cpp | 70 +++++- llvm/test/TableGen/directive1.td | 21 +- llvm/test/TableGen/directive2.td | 21 +- llvm/unittests/Frontend/CMakeLists.txt | 1 + llvm/unittests/Frontend/OpenMPComposeTest.cpp | 41 ++++ llvm/utils/TableGen/DirectiveEmitter.cpp | 226 ++++++++++++------ 7 files changed, 301 insertions(+), 86 deletions(-) create mode 100644 llvm/unittests/Frontend/OpenMPComposeTest.cpp diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.h b/llvm/include/llvm/Frontend/OpenMP/OMP.h index a85cd9d344c6..4ed47f15dfe5 100644 --- a/llvm/include/llvm/Frontend/OpenMP/OMP.h +++ b/llvm/include/llvm/Frontend/OpenMP/OMP.h @@ -15,4 +15,11 @@ #include "llvm/Frontend/OpenMP/OMP.h.inc" +#include "llvm/ADT/ArrayRef.h" + +namespace llvm::omp { +ArrayRef getLeafConstructs(Directive D); +Directive getCompoundConstruct(ArrayRef Parts); +} // namespace llvm::omp + #endif // LLVM_FRONTEND_OPENMP_OMP_H diff --git a/llvm/lib/Frontend/OpenMP/OMP.cpp b/llvm/lib/Frontend/OpenMP/OMP.cpp index 4f2f95392648..e958bced3a42 100644 --- a/llvm/lib/Frontend/OpenMP/OMP.cpp +++ b/llvm/lib/Frontend/OpenMP/OMP.cpp @@ -8,12 +8,80 @@ #include "llvm/Frontend/OpenMP/OMP.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Support/ErrorHandling.h" +#include +#include +#include + using namespace llvm; -using namespace omp; +using namespace llvm::omp; #define GEN_DIRECTIVES_IMPL #include "llvm/Frontend/OpenMP/OMP.inc" + +namespace llvm::omp { +ArrayRef getLeafConstructs(Directive D) { + auto Idx = static_cast(D); + if (Idx >= Directive_enumSize) + std::nullopt; + const auto *Row = LeafConstructTable[LeafConstructTableOrdering[Idx]]; + return ArrayRef(&Row[2], static_cast(Row[1])); +} + +Directive getCompoundConstruct(ArrayRef Parts) { + if (Parts.empty()) + return OMPD_unknown; + + // Parts don't have to be leafs, so expand them into leafs first. + // Store the expanded leafs in the same format as rows in the leaf + // table (generated by tablegen). + SmallVector RawLeafs(2); + for (Directive P : Parts) { + ArrayRef Ls = getLeafConstructs(P); + if (!Ls.empty()) + RawLeafs.append(Ls.begin(), Ls.end()); + else + RawLeafs.push_back(P); + } + + // RawLeafs will be used as key in the binary search. The search doesn't + // guarantee that the exact same entry will be found (since RawLeafs may + // not correspond to any compound directive). Because of that, we will + // need to compare the search result with the given set of leafs. + // Also, if there is only one leaf in the list, it corresponds to itself, + // no search is necessary. + auto GivenLeafs{ArrayRef(RawLeafs).drop_front(2)}; + if (GivenLeafs.size() == 1) + return GivenLeafs.front(); + RawLeafs[1] = static_cast(GivenLeafs.size()); + + auto Iter = std::lower_bound( + LeafConstructTable, LeafConstructTableEndDirective, + static_cast>(RawLeafs.data()), + [](const llvm::omp::Directive *RowA, const llvm::omp::Directive *RowB) { + const auto *BeginA = &RowA[2]; + const auto *EndA = BeginA + static_cast(RowA[1]); + const auto *BeginB = &RowB[2]; + const auto *EndB = BeginB + static_cast(RowB[1]); + if (BeginA == EndA && BeginB == EndB) + return static_cast(RowA[0]) < static_cast(RowB[0]); + return std::lexicographical_compare(BeginA, EndA, BeginB, EndB); + }); + + if (Iter == std::end(LeafConstructTable)) + return OMPD_unknown; + + // Verify that we got a match. + Directive Found = (*Iter)[0]; + ArrayRef FoundLeafs = getLeafConstructs(Found); + if (FoundLeafs == GivenLeafs) + return Found; + return OMPD_unknown; +} +} // namespace llvm::omp diff --git a/llvm/test/TableGen/directive1.td b/llvm/test/TableGen/directive1.td index 3184f625ead9..526dcb3c3bf0 100644 --- a/llvm/test/TableGen/directive1.td +++ b/llvm/test/TableGen/directive1.td @@ -52,6 +52,7 @@ def TDL_DirA : Directive<"dira"> { // CHECK-EMPTY: // CHECK-NEXT: #include "llvm/ADT/ArrayRef.h" // CHECK-NEXT: #include "llvm/ADT/BitmaskEnum.h" +// CHECK-NEXT: #include // CHECK-EMPTY: // CHECK-NEXT: namespace llvm { // CHECK-NEXT: class StringRef; @@ -112,7 +113,7 @@ def TDL_DirA : Directive<"dira"> { // CHECK-NEXT: /// Return true if \p C is a valid clause for \p D in version \p Version. // CHECK-NEXT: bool isAllowedClauseForDirective(Directive D, Clause C, unsigned Version); // CHECK-EMPTY: -// CHECK-NEXT: llvm::ArrayRef getLeafConstructs(Directive D); +// CHECK-NEXT: constexpr std::size_t getMaxLeafCount() { return 0; } // CHECK-NEXT: Association getDirectiveAssociation(Directive D); // CHECK-NEXT: AKind getAKind(StringRef); // CHECK-NEXT: llvm::StringRef getTdlAKindName(AKind); @@ -359,13 +360,6 @@ def TDL_DirA : Directive<"dira"> { // IMPL-NEXT: llvm_unreachable("Invalid Tdl Directive kind"); // IMPL-NEXT: } // IMPL-EMPTY: -// IMPL-NEXT: llvm::ArrayRef llvm::tdl::getLeafConstructs(llvm::tdl::Directive Dir) { -// IMPL-NEXT: switch (Dir) { -// IMPL-NEXT: default: -// IMPL-NEXT: return ArrayRef{}; -// IMPL-NEXT: } // switch (Dir) -// IMPL-NEXT: } -// IMPL-EMPTY: // IMPL-NEXT: llvm::tdl::Association llvm::tdl::getDirectiveAssociation(llvm::tdl::Directive Dir) { // IMPL-NEXT: switch (Dir) { // IMPL-NEXT: case llvm::tdl::Directive::TDLD_dira: @@ -374,4 +368,15 @@ def TDL_DirA : Directive<"dira"> { // IMPL-NEXT: llvm_unreachable("Unexpected directive"); // IMPL-NEXT: } // IMPL-EMPTY: +// IMPL-NEXT: static_assert(sizeof(llvm::tdl::Directive) == sizeof(int)); +// IMPL-NEXT: {{.*}} static const llvm::tdl::Directive LeafConstructTable[][2] = { +// IMPL-NEXT: llvm::tdl::TDLD_dira, static_cast(0), +// IMPL-NEXT: }; +// IMPL-EMPTY: +// IMPL-NEXT: {{.*}} static auto LeafConstructTableEndDirective = LeafConstructTable + 1; +// IMPL-EMPTY: +// IMPL-NEXT: {{.*}} static const int LeafConstructTableOrdering[] = { +// IMPL-NEXT: 0, +// IMPL-NEXT: }; +// IMPL-EMPTY: // IMPL-NEXT: #endif // GEN_DIRECTIVES_IMPL diff --git a/llvm/test/TableGen/directive2.td b/llvm/test/TableGen/directive2.td index d6fa4835c8df..9df8a06d3e51 100644 --- a/llvm/test/TableGen/directive2.td +++ b/llvm/test/TableGen/directive2.td @@ -45,6 +45,7 @@ def TDL_DirA : Directive<"dira"> { // CHECK-NEXT: #define LLVM_Tdl_INC // CHECK-EMPTY: // CHECK-NEXT: #include "llvm/ADT/ArrayRef.h" +// CHECK-NEXT: #include // CHECK-EMPTY: // CHECK-NEXT: namespace llvm { // CHECK-NEXT: class StringRef; @@ -88,7 +89,7 @@ def TDL_DirA : Directive<"dira"> { // CHECK-NEXT: /// Return true if \p C is a valid clause for \p D in version \p Version. // CHECK-NEXT: bool isAllowedClauseForDirective(Directive D, Clause C, unsigned Version); // CHECK-EMPTY: -// CHECK-NEXT: llvm::ArrayRef getLeafConstructs(Directive D); +// CHECK-NEXT: constexpr std::size_t getMaxLeafCount() { return 0; } // CHECK-NEXT: Association getDirectiveAssociation(Directive D); // CHECK-NEXT: } // namespace tdl // CHECK-NEXT: } // namespace llvm @@ -290,13 +291,6 @@ def TDL_DirA : Directive<"dira"> { // IMPL-NEXT: llvm_unreachable("Invalid Tdl Directive kind"); // IMPL-NEXT: } // IMPL-EMPTY: -// IMPL-NEXT: llvm::ArrayRef llvm::tdl::getLeafConstructs(llvm::tdl::Directive Dir) { -// IMPL-NEXT: switch (Dir) { -// IMPL-NEXT: default: -// IMPL-NEXT: return ArrayRef{}; -// IMPL-NEXT: } // switch (Dir) -// IMPL-NEXT: } -// IMPL-EMPTY: // IMPL-NEXT: llvm::tdl::Association llvm::tdl::getDirectiveAssociation(llvm::tdl::Directive Dir) { // IMPL-NEXT: switch (Dir) { // IMPL-NEXT: case llvm::tdl::Directive::TDLD_dira: @@ -305,4 +299,15 @@ def TDL_DirA : Directive<"dira"> { // IMPL-NEXT: llvm_unreachable("Unexpected directive"); // IMPL-NEXT: } // IMPL-EMPTY: +// IMPL-NEXT: static_assert(sizeof(llvm::tdl::Directive) == sizeof(int)); +// IMPL-NEXT: {{.*}} static const llvm::tdl::Directive LeafConstructTable[][2] = { +// IMPL-NEXT: llvm::tdl::TDLD_dira, static_cast(0), +// IMPL-NEXT: }; +// IMPL-EMPTY: +// IMPL-NEXT: {{.*}} static auto LeafConstructTableEndDirective = LeafConstructTable + 1; +// IMPL-EMPTY: +// IMPL-NEXT: {{.*}} static const int LeafConstructTableOrdering[] = { +// IMPL-NEXT: 0, +// IMPL-NEXT: }; +// IMPL-EMPTY: // IMPL-NEXT: #endif // GEN_DIRECTIVES_IMPL diff --git a/llvm/unittests/Frontend/CMakeLists.txt b/llvm/unittests/Frontend/CMakeLists.txt index c6f60142d627..ddb6a16cbb98 100644 --- a/llvm/unittests/Frontend/CMakeLists.txt +++ b/llvm/unittests/Frontend/CMakeLists.txt @@ -14,6 +14,7 @@ add_llvm_unittest(LLVMFrontendTests OpenMPContextTest.cpp OpenMPIRBuilderTest.cpp OpenMPParsingTest.cpp + OpenMPComposeTest.cpp DEPENDS acc_gen diff --git a/llvm/unittests/Frontend/OpenMPComposeTest.cpp b/llvm/unittests/Frontend/OpenMPComposeTest.cpp new file mode 100644 index 000000000000..c5fbe6ec6adf --- /dev/null +++ b/llvm/unittests/Frontend/OpenMPComposeTest.cpp @@ -0,0 +1,41 @@ +//===- llvm/unittests/Frontend/OpenMPComposeTest.cpp ----------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/Frontend/OpenMP/OMP.h" +#include "gtest/gtest.h" + +using namespace llvm; +using namespace llvm::omp; + +TEST(Composition, GetLeafConstructs) { + ArrayRef L1 = getLeafConstructs(OMPD_loop); + ASSERT_EQ(L1, (ArrayRef{})); + ArrayRef L2 = getLeafConstructs(OMPD_parallel_for); + ASSERT_EQ(L2, (ArrayRef{OMPD_parallel, OMPD_for})); + ArrayRef L3 = getLeafConstructs(OMPD_parallel_for_simd); + ASSERT_EQ(L3, (ArrayRef{OMPD_parallel, OMPD_for, OMPD_simd})); +} + +TEST(Composition, GetCompoundConstruct) { + Directive C1 = + getCompoundConstruct({OMPD_target, OMPD_teams, OMPD_distribute}); + ASSERT_EQ(C1, OMPD_target_teams_distribute); + Directive C2 = getCompoundConstruct({OMPD_target}); + ASSERT_EQ(C2, OMPD_target); + Directive C3 = getCompoundConstruct({OMPD_target, OMPD_masked}); + ASSERT_EQ(C3, OMPD_unknown); + Directive C4 = getCompoundConstruct({OMPD_target, OMPD_teams_distribute}); + ASSERT_EQ(C4, OMPD_target_teams_distribute); + Directive C5 = getCompoundConstruct({}); + ASSERT_EQ(C5, OMPD_unknown); + Directive C6 = getCompoundConstruct({OMPD_parallel_for, OMPD_simd}); + ASSERT_EQ(C6, OMPD_parallel_for_simd); + Directive C7 = getCompoundConstruct({OMPD_do, OMPD_simd}); + ASSERT_EQ(C7, OMPD_do_simd); // Make sure it's not OMPD_end_do_simd +} diff --git a/llvm/utils/TableGen/DirectiveEmitter.cpp b/llvm/utils/TableGen/DirectiveEmitter.cpp index e0edf1720f8a..69d9c5e8325a 100644 --- a/llvm/utils/TableGen/DirectiveEmitter.cpp +++ b/llvm/utils/TableGen/DirectiveEmitter.cpp @@ -12,6 +12,8 @@ //===----------------------------------------------------------------------===// #include "llvm/TableGen/DirectiveEmitter.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/DenseSet.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringSet.h" @@ -20,6 +22,9 @@ #include "llvm/TableGen/Record.h" #include "llvm/TableGen/TableGenBackend.h" +#include +#include + using namespace llvm; namespace { @@ -39,7 +44,8 @@ private: }; } // namespace -// Generate enum class +// Generate enum class. Entries are emitted in the order in which they appear +// in the `Records` vector. static void GenerateEnumClass(const std::vector &Records, raw_ostream &OS, StringRef Enum, StringRef Prefix, const DirectiveLanguage &DirLang, @@ -175,6 +181,16 @@ bool DirectiveLanguage::HasValidityErrors() const { return HasDuplicateClausesInDirectives(getDirectives()); } +// Count the maximum number of leaf constituents per construct. +static size_t GetMaxLeafCount(const DirectiveLanguage &DirLang) { + size_t MaxCount = 0; + for (Record *R : DirLang.getDirectives()) { + size_t Count = Directive{R}.getLeafConstructs().size(); + MaxCount = std::max(MaxCount, Count); + } + return MaxCount; +} + // Generate the declaration section for the enumeration in the directive // language static void EmitDirectivesDecl(RecordKeeper &Records, raw_ostream &OS) { @@ -189,6 +205,7 @@ static void EmitDirectivesDecl(RecordKeeper &Records, raw_ostream &OS) { if (DirLang.hasEnableBitmaskEnumInNamespace()) OS << "#include \"llvm/ADT/BitmaskEnum.h\"\n"; + OS << "#include \n"; // for size_t OS << "\n"; OS << "namespace llvm {\n"; OS << "class StringRef;\n"; @@ -244,7 +261,8 @@ static void EmitDirectivesDecl(RecordKeeper &Records, raw_ostream &OS) { OS << "bool isAllowedClauseForDirective(Directive D, " << "Clause C, unsigned Version);\n"; OS << "\n"; - OS << "llvm::ArrayRef getLeafConstructs(Directive D);\n"; + OS << "constexpr std::size_t getMaxLeafCount() { return " + << GetMaxLeafCount(DirLang) << "; }\n"; OS << "Association getDirectiveAssociation(Directive D);\n"; if (EnumHelperFuncs.length() > 0) { OS << EnumHelperFuncs; @@ -396,6 +414,19 @@ GenerateCaseForVersionedClauses(const std::vector &Clauses, } } +static std::string GetDirectiveName(const DirectiveLanguage &DirLang, + const Record *Rec) { + Directive Dir{Rec}; + return (llvm::Twine("llvm::") + DirLang.getCppNamespace() + + "::" + DirLang.getDirectivePrefix() + Dir.getFormattedName()) + .str(); +} + +static std::string GetDirectiveType(const DirectiveLanguage &DirLang) { + return (llvm::Twine("llvm::") + DirLang.getCppNamespace() + "::Directive") + .str(); +} + // Generate the isAllowedClauseForDirective function implementation. static void GenerateIsAllowedClause(const DirectiveLanguage &DirLang, raw_ostream &OS) { @@ -450,77 +481,134 @@ static void GenerateIsAllowedClause(const DirectiveLanguage &DirLang, OS << "}\n"; // End of function isAllowedClauseForDirective } -// Generate the getLeafConstructs function implementation. -static void GenerateGetLeafConstructs(const DirectiveLanguage &DirLang, - raw_ostream &OS) { - auto getQualifiedName = [&](StringRef Formatted) -> std::string { - return (llvm::Twine("llvm::") + DirLang.getCppNamespace() + - "::Directive::" + DirLang.getDirectivePrefix() + Formatted) - .str(); - }; - - // For each list of leaves, generate a static local object, then - // return a reference to that object for a given directive, e.g. +static void EmitLeafTable(const DirectiveLanguage &DirLang, raw_ostream &OS, + StringRef TableName) { + // The leaf constructs are emitted in a form of a 2D table, where each + // row corresponds to a directive (and there is a row for each directive). // - // static ListTy leafConstructs_A_B = { A, B }; - // static ListTy leafConstructs_C_D_E = { C, D, E }; - // switch (Dir) { - // case A_B: - // return leafConstructs_A_B; - // case C_D_E: - // return leafConstructs_C_D_E; - // } - - // Map from a record that defines a directive to the name of the - // local object with the list of its leaves. - DenseMap ListNames; - - std::string DirectiveTypeName = - std::string("llvm::") + DirLang.getCppNamespace().str() + "::Directive"; - - OS << '\n'; - - // ArrayRef<...> llvm::::GetLeafConstructs(llvm::::Directive Dir) - OS << "llvm::ArrayRef<" << DirectiveTypeName - << "> llvm::" << DirLang.getCppNamespace() << "::getLeafConstructs(" - << DirectiveTypeName << " Dir) "; - OS << "{\n"; + // Each row consists of + // - the id of the directive itself, + // - number of leaf constructs that will follow (0 for leafs), + // - ids of the leaf constructs (none if the directive is itself a leaf). + // The total number of these entries is at most MaxLeafCount+2. If this + // number is less than that, it is padded to occupy exactly MaxLeafCount+2 + // entries in memory. + // + // The rows are stored in the table in the lexicographical order. This + // is intended to enable binary search when mapping a sequence of leafs + // back to the compound directive. + // The consequence of that is that in order to find a row corresponding + // to the given directive, we'd need to scan the first element of each + // row. To avoid this, an auxiliary ordering table is created, such that + // row for Dir_A = table[auxiliary[Dir_A]]. + + std::vector Directives = DirLang.getDirectives(); + DenseMap DirId; // Record * -> llvm::omp::Directive + + for (auto [Idx, Rec] : llvm::enumerate(Directives)) + DirId.insert(std::make_pair(Rec, Idx)); + + using LeafList = std::vector; + int MaxLeafCount = GetMaxLeafCount(DirLang); + + // The initial leaf table, rows order is same as directive order. + std::vector LeafTable(Directives.size()); + for (auto [Idx, Rec] : llvm::enumerate(Directives)) { + Directive Dir{Rec}; + std::vector Leaves = Dir.getLeafConstructs(); + + auto &List = LeafTable[Idx]; + List.resize(MaxLeafCount + 2); + List[0] = Idx; // The id of the directive itself. + List[1] = Leaves.size(); // The number of leaves to follow. + + for (int I = 0; I != MaxLeafCount; ++I) + List[I + 2] = + static_cast(I) < Leaves.size() ? DirId.at(Leaves[I]) : -1; + } - // Generate the locals. - for (Record *R : DirLang.getDirectives()) { - Directive Dir{R}; + // Some Fortran directives are delimited, i.e. they have the form of + // "directive"---"end directive". If "directive" is a compound construct, + // then the set of leaf constituents will be nonempty and the same for + // both directives. Given this set of leafs, looking up the corresponding + // compound directive should return "directive", and not "end directive". + // To avoid this problem, gather all "end directives" at the end of the + // leaf table, and only do the search on the initial segment of the table + // that excludes the "end directives". + // It's safe to find all directives whose names begin with "end ". The + // problem only exists for compound directives, like "end do simd". + // All existing directives with names starting with "end " are either + // "end directives" for an existing "directive", or leaf directives + // (such as "end declare target"). + DenseSet EndDirectives; + for (auto [Rec, Id] : DirId) { + if (Directive{Rec}.getName().starts_with_insensitive("end ")) + EndDirectives.insert(Id); + } - std::vector LeafConstructs = Dir.getLeafConstructs(); - if (LeafConstructs.empty()) - continue; + // Avoid sorting the vector array, instead sort an index array. + // It will also be useful later to create the auxiliary indexing array. + std::vector Ordering(Directives.size()); + std::iota(Ordering.begin(), Ordering.end(), 0); + + llvm::sort(Ordering, [&](int A, int B) { + auto &LeavesA = LeafTable[A]; + auto &LeavesB = LeafTable[B]; + int DirA = LeavesA[0], DirB = LeavesB[0]; + // First of all, end directives compare greater than non-end directives. + int IsEndA = EndDirectives.count(DirA), IsEndB = EndDirectives.count(DirB); + if (IsEndA != IsEndB) + return IsEndA < IsEndB; + if (LeavesA[1] == 0 && LeavesB[1] == 0) + return DirA < DirB; + return std::lexicographical_compare(&LeavesA[2], &LeavesA[2] + LeavesA[1], + &LeavesB[2], &LeavesB[2] + LeavesB[1]); + }); - std::string ListName = "leafConstructs_" + Dir.getFormattedName(); - OS << " static const " << DirectiveTypeName << ' ' << ListName - << "[] = {\n"; - for (Record *L : LeafConstructs) { - Directive LeafDir{L}; - OS << " " << getQualifiedName(LeafDir.getFormattedName()) << ",\n"; + // Emit the table + + // The directives are emitted into a scoped enum, for which the underlying + // type is `int` (by default). The code above uses `int` to store directive + // ids, so make sure that we catch it when something changes in the + // underlying type. + std::string DirectiveType = GetDirectiveType(DirLang); + OS << "\nstatic_assert(sizeof(" << DirectiveType << ") == sizeof(int));\n"; + + OS << "[[maybe_unused]] static const " << DirectiveType << ' ' << TableName + << "[][" << MaxLeafCount + 2 << "] = {\n"; + for (size_t I = 0, E = Directives.size(); I != E; ++I) { + auto &Leaves = LeafTable[Ordering[I]]; + OS << " " << GetDirectiveName(DirLang, Directives[Leaves[0]]); + OS << ", static_cast<" << DirectiveType << ">(" << Leaves[1] << "),"; + for (size_t I = 2, E = Leaves.size(); I != E; ++I) { + int Idx = Leaves[I]; + if (Idx >= 0) + OS << ' ' << GetDirectiveName(DirLang, Directives[Leaves[I]]) << ','; + else + OS << " static_cast<" << DirectiveType << ">(-1),"; } - OS << " };\n"; - ListNames.insert(std::make_pair(R, std::move(ListName))); - } - - if (!ListNames.empty()) OS << '\n'; - OS << " switch (Dir) {\n"; - for (Record *R : DirLang.getDirectives()) { - auto F = ListNames.find(R); - if (F == ListNames.end()) - continue; - - Directive Dir{R}; - OS << " case " << getQualifiedName(Dir.getFormattedName()) << ":\n"; - OS << " return " << F->second << ";\n"; } - OS << " default:\n"; - OS << " return ArrayRef<" << DirectiveTypeName << ">{};\n"; - OS << " } // switch (Dir)\n"; - OS << "}\n"; + OS << "};\n\n"; + + // Emit a marker where the first "end directive" is. + auto FirstE = llvm::find_if(Ordering, [&](int RowIdx) { + return EndDirectives.count(LeafTable[RowIdx][0]); + }); + OS << "[[maybe_unused]] static auto " << TableName + << "EndDirective = " << TableName << " + " + << std::distance(Ordering.begin(), FirstE) << ";\n\n"; + + // Emit the auxiliary index table: it's the inverse of the `Ordering` + // table above. + OS << "[[maybe_unused]] static const int " << TableName << "Ordering[] = {\n"; + OS << " "; + std::vector Reverse(Ordering.size()); + for (int I = 0, E = Ordering.size(); I != E; ++I) + Reverse[Ordering[I]] = I; + for (int Idx : Reverse) + OS << ' ' << Idx << ','; + OS << "\n};\n"; } static void GenerateGetDirectiveAssociation(const DirectiveLanguage &DirLang, @@ -1105,11 +1193,11 @@ void EmitDirectivesBasicImpl(const DirectiveLanguage &DirLang, // isAllowedClauseForDirective(Directive D, Clause C, unsigned Version) GenerateIsAllowedClause(DirLang, OS); - // getLeafConstructs(Directive D) - GenerateGetLeafConstructs(DirLang, OS); - // getDirectiveAssociation(Directive D) GenerateGetDirectiveAssociation(DirLang, OS); + + // Leaf table for getLeafConstructs, etc. + EmitLeafTable(DirLang, OS, "LeafConstructTable"); } // Generate the implemenation section for the enumeration in the directive -- GitLab From 99f42e6b88177328ebe725b5cb6d422106bbb3e6 Mon Sep 17 00:00:00 2001 From: Xu Jun <693788454@qq.com> Date: Tue, 23 Apr 2024 03:51:11 +0800 Subject: [PATCH 028/732] [lldb][dap] always add column field in StackFrame body (#73393) The `column` field is mandatory in StackTraceResponse, otherwise the debugger client may raise error (e.g. VSCode can't correctly open an editor without the column field) --------- Signed-off-by: Xu Jun <693788454@qq.com> --- lldb/tools/lldb-dap/JSONUtils.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp b/lldb/tools/lldb-dap/JSONUtils.cpp index 878449a91aa6..b4a2718bbb09 100644 --- a/lldb/tools/lldb-dap/JSONUtils.cpp +++ b/lldb/tools/lldb-dap/JSONUtils.cpp @@ -748,9 +748,10 @@ llvm::json::Value CreateStackFrame(lldb::SBFrame &frame) { auto line = line_entry.GetLine(); if (line && line != LLDB_INVALID_LINE_NUMBER) object.try_emplace("line", line); + else + object.try_emplace("line", 0); auto column = line_entry.GetColumn(); - if (column && column != LLDB_INVALID_COLUMN_NUMBER) - object.try_emplace("column", column); + object.try_emplace("column", column); } else { object.try_emplace("line", 0); object.try_emplace("column", 0); -- GitLab From bcd150d2906ac83ea0ab680e981770a71c021a03 Mon Sep 17 00:00:00 2001 From: LLVM GN Syncbot Date: Mon, 22 Apr 2024 19:56:11 +0000 Subject: [PATCH 029/732] [gn build] Port 40137ff0d81b --- llvm/utils/gn/secondary/llvm/unittests/Frontend/BUILD.gn | 1 + 1 file changed, 1 insertion(+) diff --git a/llvm/utils/gn/secondary/llvm/unittests/Frontend/BUILD.gn b/llvm/utils/gn/secondary/llvm/unittests/Frontend/BUILD.gn index 9648fac135b6..c78ea923aae8 100644 --- a/llvm/utils/gn/secondary/llvm/unittests/Frontend/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/unittests/Frontend/BUILD.gn @@ -13,6 +13,7 @@ unittest("LLVMFrontendTests") { ] sources = [ "OpenACCTest.cpp", + "OpenMPComposeTest.cpp", "OpenMPContextTest.cpp", "OpenMPIRBuilderTest.cpp", "OpenMPParsingTest.cpp", -- GitLab From 7c5854673391940d578c591c727614bf50b78301 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20Degioanni?= Date: Mon, 22 Apr 2024 22:03:56 +0200 Subject: [PATCH 030/732] [nfc][llvm] Fix a typo in MathExtras.h testing (#89653) I made a small typo when writing a test for MathExtras.h, sorry! --- llvm/unittests/Support/MathExtrasTest.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/llvm/unittests/Support/MathExtrasTest.cpp b/llvm/unittests/Support/MathExtrasTest.cpp index 218655851ca0..d09f987b9d0f 100644 --- a/llvm/unittests/Support/MathExtrasTest.cpp +++ b/llvm/unittests/Support/MathExtrasTest.cpp @@ -41,9 +41,9 @@ TEST(MathExtras, onesMask) { TEST(MathExtras, isIntN) { EXPECT_TRUE(isIntN(16, 32767)); EXPECT_FALSE(isIntN(16, 32768)); - EXPECT_TRUE(isUIntN(0, 0)); - EXPECT_FALSE(isUIntN(0, 1)); - EXPECT_FALSE(isUIntN(0, -1)); + EXPECT_TRUE(isIntN(0, 0)); + EXPECT_FALSE(isIntN(0, 1)); + EXPECT_FALSE(isIntN(0, -1)); } TEST(MathExtras, isUIntN) { -- GitLab From 83bc7b57714dc2f6b33c188f2b95a0025468ba51 Mon Sep 17 00:00:00 2001 From: Nikolas Klauser Date: Mon, 22 Apr 2024 22:13:58 +0200 Subject: [PATCH 031/732] [libc++] Remove _LIBCPP_DISABLE_NODISCARD_EXTENSIONS and refactor the tests (#87094) This also adds a few tests that were missing. --- libcxx/.clang-format | 1 - libcxx/docs/ReleaseNotes/19.rst | 4 + libcxx/docs/UsingLibcxx.rst | 27 --- libcxx/include/__algorithm/adjacent_find.h | 6 +- libcxx/include/__algorithm/all_of.h | 2 +- libcxx/include/__algorithm/any_of.h | 2 +- libcxx/include/__algorithm/binary_search.h | 4 +- libcxx/include/__algorithm/clamp.h | 4 +- libcxx/include/__algorithm/count.h | 2 +- libcxx/include/__algorithm/count_if.h | 6 +- libcxx/include/__algorithm/equal.h | 8 +- libcxx/include/__algorithm/equal_range.h | 4 +- libcxx/include/__algorithm/find.h | 2 +- libcxx/include/__algorithm/find_end.h | 4 +- libcxx/include/__algorithm/find_first_of.h | 4 +- libcxx/include/__algorithm/find_if.h | 2 +- libcxx/include/__algorithm/find_if_not.h | 2 +- libcxx/include/__algorithm/fold.h | 10 +- libcxx/include/__algorithm/includes.h | 4 +- libcxx/include/__algorithm/is_heap.h | 4 +- libcxx/include/__algorithm/is_heap_until.h | 4 +- libcxx/include/__algorithm/is_partitioned.h | 2 +- libcxx/include/__algorithm/is_permutation.h | 10 +- libcxx/include/__algorithm/is_sorted.h | 4 +- libcxx/include/__algorithm/is_sorted_until.h | 4 +- .../__algorithm/lexicographical_compare.h | 4 +- .../lexicographical_compare_three_way.h | 4 +- libcxx/include/__algorithm/lower_bound.h | 4 +- libcxx/include/__algorithm/max.h | 8 +- libcxx/include/__algorithm/max_element.h | 4 +- libcxx/include/__algorithm/min.h | 8 +- libcxx/include/__algorithm/min_element.h | 4 +- libcxx/include/__algorithm/minmax.h | 8 +- libcxx/include/__algorithm/minmax_element.h | 7 +- libcxx/include/__algorithm/mismatch.h | 12 +- libcxx/include/__algorithm/none_of.h | 2 +- .../__algorithm/pstl_any_all_none_of.h | 6 +- .../include/__algorithm/pstl_is_partitioned.h | 2 +- .../__algorithm/ranges_adjacent_find.h | 4 +- libcxx/include/__algorithm/ranges_all_of.h | 4 +- libcxx/include/__algorithm/ranges_any_of.h | 4 +- .../__algorithm/ranges_binary_search.h | 4 +- libcxx/include/__algorithm/ranges_clamp.h | 2 +- libcxx/include/__algorithm/ranges_contains.h | 4 +- .../__algorithm/ranges_contains_subrange.h | 4 +- libcxx/include/__algorithm/ranges_count.h | 4 +- libcxx/include/__algorithm/ranges_count_if.h | 4 +- libcxx/include/__algorithm/ranges_ends_with.h | 4 +- libcxx/include/__algorithm/ranges_equal.h | 4 +- .../include/__algorithm/ranges_equal_range.h | 4 +- libcxx/include/__algorithm/ranges_find.h | 4 +- libcxx/include/__algorithm/ranges_find_end.h | 4 +- .../__algorithm/ranges_find_first_of.h | 4 +- libcxx/include/__algorithm/ranges_find_if.h | 4 +- .../include/__algorithm/ranges_find_if_not.h | 4 +- libcxx/include/__algorithm/ranges_includes.h | 4 +- libcxx/include/__algorithm/ranges_is_heap.h | 4 +- .../__algorithm/ranges_is_heap_until.h | 4 +- .../__algorithm/ranges_is_partitioned.h | 4 +- .../__algorithm/ranges_is_permutation.h | 4 +- libcxx/include/__algorithm/ranges_is_sorted.h | 4 +- .../__algorithm/ranges_is_sorted_until.h | 4 +- .../ranges_lexicographical_compare.h | 4 +- .../include/__algorithm/ranges_lower_bound.h | 4 +- libcxx/include/__algorithm/ranges_max.h | 6 +- .../include/__algorithm/ranges_max_element.h | 4 +- libcxx/include/__algorithm/ranges_min.h | 6 +- .../include/__algorithm/ranges_min_element.h | 4 +- libcxx/include/__algorithm/ranges_minmax.h | 6 +- .../__algorithm/ranges_minmax_element.h | 4 +- libcxx/include/__algorithm/ranges_mismatch.h | 4 +- libcxx/include/__algorithm/ranges_none_of.h | 4 +- libcxx/include/__algorithm/ranges_remove.h | 4 +- libcxx/include/__algorithm/ranges_remove_if.h | 4 +- libcxx/include/__algorithm/ranges_search.h | 4 +- libcxx/include/__algorithm/ranges_search_n.h | 4 +- .../include/__algorithm/ranges_starts_with.h | 4 +- libcxx/include/__algorithm/ranges_unique.h | 4 +- .../include/__algorithm/ranges_upper_bound.h | 4 +- libcxx/include/__algorithm/remove.h | 2 +- libcxx/include/__algorithm/remove_if.h | 2 +- libcxx/include/__algorithm/search.h | 6 +- libcxx/include/__algorithm/search_n.h | 4 +- libcxx/include/__algorithm/unique.h | 6 +- libcxx/include/__algorithm/upper_bound.h | 4 +- libcxx/include/__bit/bit_cast.h | 2 +- libcxx/include/__bit/bit_ceil.h | 4 +- libcxx/include/__bit/bit_floor.h | 2 +- libcxx/include/__bit/bit_width.h | 2 +- libcxx/include/__bit/byteswap.h | 2 +- libcxx/include/__bit/countl.h | 4 +- libcxx/include/__bit/countr.h | 4 +- libcxx/include/__bit/has_single_bit.h | 2 +- libcxx/include/__bit/popcount.h | 2 +- libcxx/include/__chrono/leap_second.h | 4 +- libcxx/include/__chrono/time_zone.h | 8 +- libcxx/include/__chrono/time_zone_link.h | 10 +- libcxx/include/__chrono/tzdb.h | 4 +- libcxx/include/__chrono/tzdb_list.h | 21 +- libcxx/include/__config | 16 +- libcxx/include/__filesystem/path.h | 2 +- libcxx/include/__format/format_functions.h | 30 ++- libcxx/include/__functional/identity.h | 2 +- libcxx/include/__iterator/empty.h | 8 +- libcxx/include/__math/abs.h | 8 +- libcxx/include/__math/copysign.h | 7 +- libcxx/include/__math/min_max.h | 16 +- libcxx/include/__math/roots.h | 8 +- libcxx/include/__math/rounding_functions.h | 48 ++--- libcxx/include/__math/traits.h | 46 ++--- libcxx/include/__memory/allocator.h | 10 +- libcxx/include/__memory/allocator_traits.h | 6 +- libcxx/include/__memory/temporary_buffer.h | 2 +- .../__memory_resource/memory_resource.h | 5 +- .../__memory_resource/polymorphic_allocator.h | 2 +- libcxx/include/__mutex/lock_guard.h | 6 +- libcxx/include/__node_handle | 2 +- libcxx/include/__ranges/as_rvalue_view.h | 4 +- libcxx/include/__ranges/chunk_by_view.h | 4 +- libcxx/include/__ranges/drop_view.h | 4 +- libcxx/include/__ranges/repeat_view.h | 4 +- libcxx/include/__ranges/split_view.h | 4 +- libcxx/include/__ranges/take_view.h | 4 +- libcxx/include/__ranges/to.h | 8 +- libcxx/include/__utility/as_const.h | 2 +- libcxx/include/__utility/forward.h | 4 +- libcxx/include/__utility/move.h | 4 +- libcxx/include/__utility/to_underlying.h | 2 +- libcxx/include/array | 4 +- libcxx/include/barrier | 4 +- libcxx/include/cstddef | 2 +- libcxx/include/deque | 2 +- libcxx/include/forward_list | 2 +- libcxx/include/future | 10 +- libcxx/include/limits | 126 ++++++------ libcxx/include/list | 2 +- libcxx/include/map | 4 +- libcxx/include/math.h | 8 +- libcxx/include/module.modulemap | 5 +- libcxx/include/new | 24 +-- libcxx/include/queue | 4 +- libcxx/include/regex | 2 +- libcxx/include/scoped_allocator | 4 +- libcxx/include/set | 4 +- libcxx/include/stack | 2 +- libcxx/include/stdlib.h | 12 +- libcxx/include/string | 2 +- libcxx/include/string_view | 2 +- libcxx/include/unordered_map | 4 +- libcxx/include/unordered_set | 4 +- libcxx/include/vector | 4 +- libcxx/src/tzdb.cpp | 4 +- ...ify.cpp => algorithm.nodiscard.verify.cpp} | 159 +++++++++------ .../diagnostics/array.nodiscard.verify.cpp | 23 +++ ...ns.verify.cpp => bit.nodiscard.verify.cpp} | 2 + .../bit.nodiscard_extensions.compile.pass.cpp | 34 ---- ...verify.cpp => chrono.nodiscard.verify.cpp} | 0 ...rono.nodiscard_extensions.compile.pass.cpp | 69 ------- ....verify.cpp => cmath.nodiscard.verify.cpp} | 2 + .../diagnostics/cstddef.nodiscard.verify.cpp} | 15 +- .../diagnostics/cstdlib.nodiscard.verify.cpp | 25 +++ .../diagnostics/deque.nodiscard.verify.cpp | 18 ++ .../filesystem.nodiscard.verify.cpp | 19 ++ ...verify.cpp => format.nodiscard.verify.cpp} | 0 ...rmat.nodiscard_extensions.compile.pass.cpp | 50 ----- .../forward_list.nodiscard.verify.cpp | 18 ++ ...ss.cpp => functional.nodiscard.verify.cpp} | 16 +- .../diagnostics/future.nodiscard.verify.cpp | 22 ++ .../diagnostics/iterator.nodiscard.verify.cpp | 26 +++ ...verify.cpp => limits.nodiscard.verify.cpp} | 0 ...mits.nodiscard_extensions.compile.pass.cpp | 71 ------- .../diagnostics/list.nodiscard.verify.cpp | 18 ++ .../diagnostics/map.nodiscard.verify.cpp | 23 +++ .../diagnostics/memory.nodiscard.verify.cpp | 53 +++++ .../memory_resource.nodiscard.verify.cpp | 25 +++ .../diagnostics/mutex.nodiscard.verify.cpp | 25 +++ .../diagnostics/new.nodiscard.verify.cpp | 35 ++++ .../node_handle.nodiscard.verify.cpp | 18 ++ .../nodiscard_extensions.compile.pass.cpp | 188 ------------------ ...s.verify.cpp => pstl.nodiscard.verify.cpp} | 9 +- ...pstl.nodiscard_extensions.compile.pass.cpp | 28 --- .../diagnostics/queue.nodiscard.verify.cpp | 23 +++ .../diagnostics/ranges.nodiscard.verify.cpp | 59 ++++++ ...nges.nodiscard_extensions.compile.pass.cpp | 101 ---------- .../ranges.nodiscard_extensions.verify.cpp | 111 ----------- ....verify.cpp => regex.nodiscard.verify.cpp} | 15 +- .../scoped_allocator.nodiscard.verify.cpp | 22 ++ .../diagnostics/set.nodiscard.verify.cpp | 23 +++ .../diagnostics/stack.nodiscard.verify.cpp | 18 ++ .../diagnostics/string.nodiscard.verify.cpp | 18 ++ .../string_view.nodiscard.verify.cpp | 18 ++ .../unordered_map.nodiscard.verify.cpp | 25 +++ .../unordered_set.nodiscard.verify.cpp | 25 +++ .../diagnostics/utility.nodiscard.verify.cpp | 35 ++++ .../diagnostics/vector.nodiscard.verify.cpp | 23 +++ ...w_adaptors.nodiscard_extensions.verify.cpp | 22 -- .../adaptor.nodiscard.verify.cpp | 26 --- .../to.nodiscard.verify.cpp | 29 --- 198 files changed, 1224 insertions(+), 1331 deletions(-) rename libcxx/test/libcxx/diagnostics/{nodiscard_extensions.verify.cpp => algorithm.nodiscard.verify.cpp} (56%) create mode 100644 libcxx/test/libcxx/diagnostics/array.nodiscard.verify.cpp rename libcxx/test/libcxx/diagnostics/{bit.nodiscard_extensions.verify.cpp => bit.nodiscard.verify.cpp} (98%) delete mode 100644 libcxx/test/libcxx/diagnostics/bit.nodiscard_extensions.compile.pass.cpp rename libcxx/test/libcxx/diagnostics/{chrono.nodiscard_extensions.verify.cpp => chrono.nodiscard.verify.cpp} (100%) delete mode 100644 libcxx/test/libcxx/diagnostics/chrono.nodiscard_extensions.compile.pass.cpp rename libcxx/test/libcxx/diagnostics/{math_nodiscard_extensions.verify.cpp => cmath.nodiscard.verify.cpp} (99%) rename libcxx/test/{std/language.support/support.dynamic/ptr.launder/launder.nodiscard.verify.cpp => libcxx/diagnostics/cstddef.nodiscard.verify.cpp} (60%) create mode 100644 libcxx/test/libcxx/diagnostics/cstdlib.nodiscard.verify.cpp create mode 100644 libcxx/test/libcxx/diagnostics/deque.nodiscard.verify.cpp create mode 100644 libcxx/test/libcxx/diagnostics/filesystem.nodiscard.verify.cpp rename libcxx/test/libcxx/diagnostics/{format.nodiscard_extensions.verify.cpp => format.nodiscard.verify.cpp} (100%) delete mode 100644 libcxx/test/libcxx/diagnostics/format.nodiscard_extensions.compile.pass.cpp create mode 100644 libcxx/test/libcxx/diagnostics/forward_list.nodiscard.verify.cpp rename libcxx/test/libcxx/diagnostics/{nodiscard.pass.cpp => functional.nodiscard.verify.cpp} (55%) create mode 100644 libcxx/test/libcxx/diagnostics/future.nodiscard.verify.cpp create mode 100644 libcxx/test/libcxx/diagnostics/iterator.nodiscard.verify.cpp rename libcxx/test/libcxx/diagnostics/{limits.nodiscard_extensions.verify.cpp => limits.nodiscard.verify.cpp} (100%) delete mode 100644 libcxx/test/libcxx/diagnostics/limits.nodiscard_extensions.compile.pass.cpp create mode 100644 libcxx/test/libcxx/diagnostics/list.nodiscard.verify.cpp create mode 100644 libcxx/test/libcxx/diagnostics/map.nodiscard.verify.cpp create mode 100644 libcxx/test/libcxx/diagnostics/memory.nodiscard.verify.cpp create mode 100644 libcxx/test/libcxx/diagnostics/memory_resource.nodiscard.verify.cpp create mode 100644 libcxx/test/libcxx/diagnostics/mutex.nodiscard.verify.cpp create mode 100644 libcxx/test/libcxx/diagnostics/new.nodiscard.verify.cpp create mode 100644 libcxx/test/libcxx/diagnostics/node_handle.nodiscard.verify.cpp delete mode 100644 libcxx/test/libcxx/diagnostics/nodiscard_extensions.compile.pass.cpp rename libcxx/test/libcxx/diagnostics/{pstl.nodiscard_extensions.verify.cpp => pstl.nodiscard.verify.cpp} (62%) delete mode 100644 libcxx/test/libcxx/diagnostics/pstl.nodiscard_extensions.compile.pass.cpp create mode 100644 libcxx/test/libcxx/diagnostics/queue.nodiscard.verify.cpp create mode 100644 libcxx/test/libcxx/diagnostics/ranges.nodiscard.verify.cpp delete mode 100644 libcxx/test/libcxx/diagnostics/ranges.nodiscard_extensions.compile.pass.cpp delete mode 100644 libcxx/test/libcxx/diagnostics/ranges.nodiscard_extensions.verify.cpp rename libcxx/test/libcxx/diagnostics/{nodiscard_aftercxx17.verify.cpp => regex.nodiscard.verify.cpp} (52%) create mode 100644 libcxx/test/libcxx/diagnostics/scoped_allocator.nodiscard.verify.cpp create mode 100644 libcxx/test/libcxx/diagnostics/set.nodiscard.verify.cpp create mode 100644 libcxx/test/libcxx/diagnostics/stack.nodiscard.verify.cpp create mode 100644 libcxx/test/libcxx/diagnostics/string.nodiscard.verify.cpp create mode 100644 libcxx/test/libcxx/diagnostics/string_view.nodiscard.verify.cpp create mode 100644 libcxx/test/libcxx/diagnostics/unordered_map.nodiscard.verify.cpp create mode 100644 libcxx/test/libcxx/diagnostics/unordered_set.nodiscard.verify.cpp create mode 100644 libcxx/test/libcxx/diagnostics/utility.nodiscard.verify.cpp create mode 100644 libcxx/test/libcxx/diagnostics/vector.nodiscard.verify.cpp delete mode 100644 libcxx/test/libcxx/diagnostics/view_adaptors.nodiscard_extensions.verify.cpp delete mode 100644 libcxx/test/libcxx/ranges/range.adaptors/range.chunk.by/adaptor.nodiscard.verify.cpp delete mode 100644 libcxx/test/libcxx/ranges/range.utility/range.utility.conv/to.nodiscard.verify.cpp diff --git a/libcxx/.clang-format b/libcxx/.clang-format index c37ab817bca9..871920f15b5b 100644 --- a/libcxx/.clang-format +++ b/libcxx/.clang-format @@ -44,7 +44,6 @@ AttributeMacros: [ '_LIBCPP_NO_SANITIZE', '_LIBCPP_NO_UNIQUE_ADDRESS', '_LIBCPP_NOALIAS', - '_LIBCPP_NODISCARD_EXT', '_LIBCPP_NODISCARD', '_LIBCPP_NORETURN', '_LIBCPP_OVERRIDABLE_FUNC_VIS', diff --git a/libcxx/docs/ReleaseNotes/19.rst b/libcxx/docs/ReleaseNotes/19.rst index 53cc7a77d1af..b466b4cd8140 100644 --- a/libcxx/docs/ReleaseNotes/19.rst +++ b/libcxx/docs/ReleaseNotes/19.rst @@ -79,6 +79,10 @@ Deprecations and Removals in language modes prior to C++20. If you are using these features prior to C++20, please update to ``-std=c++20``. In LLVM 20, the C++20 synchronization library will be removed entirely in language modes prior to C++20. +- ``_LIBCPP_DISABLE_NODISCARD_EXT`` has been removed. ``[[nodiscard]]`` applications are now unconditional. + This decision is based on LEWGs discussion on `P3122 ` and `P3162 ` + to not use ``[[nodiscard]]`` in the standard. + - TODO: The ``LIBCXX_ENABLE_ASSERTIONS`` CMake variable that was used to enable the safe mode has been deprecated and setting it triggers an error; use the ``LIBCXX_HARDENING_MODE`` CMake variable with the value ``extensive`` instead. Similarly, the ``_LIBCPP_ENABLE_ASSERTIONS`` macro has been deprecated (setting it to ``1`` still enables the extensive mode in diff --git a/libcxx/docs/UsingLibcxx.rst b/libcxx/docs/UsingLibcxx.rst index 8f945656de1c..e7aaf4e1fbcf 100644 --- a/libcxx/docs/UsingLibcxx.rst +++ b/libcxx/docs/UsingLibcxx.rst @@ -196,10 +196,6 @@ safety annotations. replacement scenarios from working, e.g. replacing `operator new` and expecting a non-replaced `operator new[]` to call the replaced `operator new`. -**_LIBCPP_DISABLE_NODISCARD_EXT**: - This macro disables library-extensions of ``[[nodiscard]]``. - See :ref:`Extended Applications of [[nodiscard]] ` for more information. - **_LIBCPP_DISABLE_DEPRECATION_WARNINGS**: This macro disables warnings when using deprecated components. For example, using `std::auto_ptr` when compiling in C++11 mode will normally trigger a @@ -279,29 +275,6 @@ Libc++ Extensions This section documents various extensions provided by libc++, how they're provided, and any information regarding how to use them. -.. _nodiscard extension: - -Extended applications of ``[[nodiscard]]`` ------------------------------------------- - -The ``[[nodiscard]]`` attribute is intended to help users find bugs where -function return values are ignored when they shouldn't be. After C++17 the -C++ standard has started to declared such library functions as ``[[nodiscard]]``. -However, this application is limited and applies only to dialects after C++17. -Users who want help diagnosing misuses of STL functions may desire a more -liberal application of ``[[nodiscard]]``. - -For this reason libc++ provides an extension that does just that! The -extension is enabled by default and can be disabled by defining ``_LIBCPP_DISABLE_NODISCARD_EXT``. -The extended applications of ``[[nodiscard]]`` takes two forms: - -1. Backporting ``[[nodiscard]]`` to entities declared as such by the - standard in newer dialects, but not in the present one. - -2. Extended applications of ``[[nodiscard]]``, at the library's discretion, - applied to entities never declared as such by the standard. You can find - all such applications by grepping for ``_LIBCPP_NODISCARD_EXT``. - Extended integral type support ------------------------------ diff --git a/libcxx/include/__algorithm/adjacent_find.h b/libcxx/include/__algorithm/adjacent_find.h index 7819e2cf49b9..6f15456e3a4d 100644 --- a/libcxx/include/__algorithm/adjacent_find.h +++ b/libcxx/include/__algorithm/adjacent_find.h @@ -26,7 +26,7 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter __adjacent_find(_Iter __first, _Sent __last, _BinaryPredicate&& __pred) { if (__first == __last) return __first; @@ -40,13 +40,13 @@ __adjacent_find(_Iter __first, _Sent __last, _BinaryPredicate&& __pred) { } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator adjacent_find(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) { return std::__adjacent_find(std::move(__first), std::move(__last), __pred); } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator adjacent_find(_ForwardIterator __first, _ForwardIterator __last) { return std::adjacent_find(std::move(__first), std::move(__last), __equal_to()); } diff --git a/libcxx/include/__algorithm/all_of.h b/libcxx/include/__algorithm/all_of.h index 237f8495c645..ec84eea75929 100644 --- a/libcxx/include/__algorithm/all_of.h +++ b/libcxx/include/__algorithm/all_of.h @@ -19,7 +19,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool all_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) { for (; __first != __last; ++__first) if (!__pred(*__first)) diff --git a/libcxx/include/__algorithm/any_of.h b/libcxx/include/__algorithm/any_of.h index 8ba7aae2b225..b5ff778c4171 100644 --- a/libcxx/include/__algorithm/any_of.h +++ b/libcxx/include/__algorithm/any_of.h @@ -19,7 +19,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool any_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) { for (; __first != __last; ++__first) if (__pred(*__first)) diff --git a/libcxx/include/__algorithm/binary_search.h b/libcxx/include/__algorithm/binary_search.h index 7a77d7b5447b..6065fc37274d 100644 --- a/libcxx/include/__algorithm/binary_search.h +++ b/libcxx/include/__algorithm/binary_search.h @@ -22,14 +22,14 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) { __first = std::lower_bound<_ForwardIterator, _Tp, __comp_ref_type<_Compare> >(__first, __last, __value, __comp); return __first != __last && !__comp(__value, *__first); } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { return std::binary_search(__first, __last, __value, __less<>()); } diff --git a/libcxx/include/__algorithm/clamp.h b/libcxx/include/__algorithm/clamp.h index 003bf70dd4f0..1a5a3d0744be 100644 --- a/libcxx/include/__algorithm/clamp.h +++ b/libcxx/include/__algorithm/clamp.h @@ -21,7 +21,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 17 template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& +[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& clamp(_LIBCPP_LIFETIMEBOUND const _Tp& __v, _LIBCPP_LIFETIMEBOUND const _Tp& __lo, _LIBCPP_LIFETIMEBOUND const _Tp& __hi, @@ -31,7 +31,7 @@ clamp(_LIBCPP_LIFETIMEBOUND const _Tp& __v, } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& +[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& clamp(_LIBCPP_LIFETIMEBOUND const _Tp& __v, _LIBCPP_LIFETIMEBOUND const _Tp& __lo, _LIBCPP_LIFETIMEBOUND const _Tp& __hi) { diff --git a/libcxx/include/__algorithm/count.h b/libcxx/include/__algorithm/count.h index 23a7d3c4dcfe..1cfe7f631ac1 100644 --- a/libcxx/include/__algorithm/count.h +++ b/libcxx/include/__algorithm/count.h @@ -79,7 +79,7 @@ __count(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __l } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __iter_diff_t<_InputIterator> +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __iter_diff_t<_InputIterator> count(_InputIterator __first, _InputIterator __last, const _Tp& __value) { __identity __proj; return std::__count<_ClassicAlgPolicy>(__first, __last, __value, __proj); diff --git a/libcxx/include/__algorithm/count_if.h b/libcxx/include/__algorithm/count_if.h index 04f52b894f8b..25782069d032 100644 --- a/libcxx/include/__algorithm/count_if.h +++ b/libcxx/include/__algorithm/count_if.h @@ -20,9 +20,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - typename iterator_traits<_InputIterator>::difference_type - count_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +typename iterator_traits<_InputIterator>::difference_type +count_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) { typename iterator_traits<_InputIterator>::difference_type __r(0); for (; __first != __last; ++__first) if (__pred(*__first)) diff --git a/libcxx/include/__algorithm/equal.h b/libcxx/include/__algorithm/equal.h index 1341d9e4159b..bfc8f72f6eb1 100644 --- a/libcxx/include/__algorithm/equal.h +++ b/libcxx/include/__algorithm/equal.h @@ -55,14 +55,14 @@ __equal_iter_impl(_Tp* __first1, _Tp* __last1, _Up* __first2, _BinaryPredicate&) } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __pred) { return std::__equal_iter_impl( std::__unwrap_iter(__first1), std::__unwrap_iter(__last1), std::__unwrap_iter(__first2), __pred); } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2) { return std::equal(__first1, __last1, __first2, __equal_to()); } @@ -96,7 +96,7 @@ __equal_impl(_Tp* __first1, _Tp* __last1, _Up* __first2, _Up*, _Pred&, _Proj1&, } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, @@ -119,7 +119,7 @@ equal(_InputIterator1 __first1, } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) { return std::equal(__first1, __last1, __first2, __last2, __equal_to()); } diff --git a/libcxx/include/__algorithm/equal_range.h b/libcxx/include/__algorithm/equal_range.h index 2b086abf1794..09bbf8f00602 100644 --- a/libcxx/include/__algorithm/equal_range.h +++ b/libcxx/include/__algorithm/equal_range.h @@ -60,7 +60,7 @@ __equal_range(_Iter __first, _Sent __last, const _Tp& __value, _Compare&& __comp } template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator, _ForwardIterator> +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator, _ForwardIterator> equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) { static_assert(__is_callable<_Compare, decltype(*__first), const _Tp&>::value, "The comparator has to be callable"); static_assert(is_copy_constructible<_ForwardIterator>::value, "Iterator has to be copy constructible"); @@ -73,7 +73,7 @@ equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __valu } template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator, _ForwardIterator> +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator, _ForwardIterator> equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { return std::equal_range(std::move(__first), std::move(__last), __value, __less<>()); } diff --git a/libcxx/include/__algorithm/find.h b/libcxx/include/__algorithm/find.h index 7d7631b6e98a..d60356873132 100644 --- a/libcxx/include/__algorithm/find.h +++ b/libcxx/include/__algorithm/find.h @@ -169,7 +169,7 @@ struct __find_segment { // public API template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator find(_InputIterator __first, _InputIterator __last, const _Tp& __value) { __identity __proj; return std::__rewrap_iter( diff --git a/libcxx/include/__algorithm/find_end.h b/libcxx/include/__algorithm/find_end.h index 4c26891666b2..7e08e7953534 100644 --- a/libcxx/include/__algorithm/find_end.h +++ b/libcxx/include/__algorithm/find_end.h @@ -205,7 +205,7 @@ _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Fo } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 find_end( +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 find_end( _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, @@ -215,7 +215,7 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) { return std::find_end(__first1, __last1, __first2, __last2, __equal_to()); } diff --git a/libcxx/include/__algorithm/find_first_of.h b/libcxx/include/__algorithm/find_first_of.h index 14271cccc42b..6b99f562f880 100644 --- a/libcxx/include/__algorithm/find_first_of.h +++ b/libcxx/include/__algorithm/find_first_of.h @@ -35,7 +35,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator1 __find_fir } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 find_first_of( +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 find_first_of( _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, @@ -45,7 +45,7 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 find_first_of( +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 find_first_of( _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) { return std::__find_first_of_ce(__first1, __last1, __first2, __last2, __equal_to()); } diff --git a/libcxx/include/__algorithm/find_if.h b/libcxx/include/__algorithm/find_if.h index 09a39f646351..22092d352b06 100644 --- a/libcxx/include/__algorithm/find_if.h +++ b/libcxx/include/__algorithm/find_if.h @@ -19,7 +19,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator find_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) { for (; __first != __last; ++__first) if (__pred(*__first)) diff --git a/libcxx/include/__algorithm/find_if_not.h b/libcxx/include/__algorithm/find_if_not.h index bf29ebb7cdd9..cc2001967f0c 100644 --- a/libcxx/include/__algorithm/find_if_not.h +++ b/libcxx/include/__algorithm/find_if_not.h @@ -19,7 +19,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator find_if_not(_InputIterator __first, _InputIterator __last, _Predicate __pred) { for (; __first != __last; ++__first) if (!__pred(*__first)) diff --git a/libcxx/include/__algorithm/fold.h b/libcxx/include/__algorithm/fold.h index 1a9d76b50d83..255658f52324 100644 --- a/libcxx/include/__algorithm/fold.h +++ b/libcxx/include/__algorithm/fold.h @@ -78,8 +78,7 @@ concept __indirectly_binary_left_foldable = struct __fold_left_with_iter { template _Sp, class _Tp, __indirectly_binary_left_foldable<_Tp, _Ip> _Fp> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI static constexpr auto - operator()(_Ip __first, _Sp __last, _Tp __init, _Fp __f) { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Ip __first, _Sp __last, _Tp __init, _Fp __f) { using _Up = decay_t>>; if (__first == __last) { @@ -95,7 +94,7 @@ struct __fold_left_with_iter { } template > _Fp> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Rp&& __r, _Tp __init, _Fp __f) { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Rp&& __r, _Tp __init, _Fp __f) { auto __result = operator()(ranges::begin(__r), ranges::end(__r), std::move(__init), std::ref(__f)); using _Up = decay_t>>; @@ -107,13 +106,12 @@ inline constexpr auto fold_left_with_iter = __fold_left_with_iter(); struct __fold_left { template _Sp, class _Tp, __indirectly_binary_left_foldable<_Tp, _Ip> _Fp> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI static constexpr auto - operator()(_Ip __first, _Sp __last, _Tp __init, _Fp __f) { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Ip __first, _Sp __last, _Tp __init, _Fp __f) { return fold_left_with_iter(std::move(__first), std::move(__last), std::move(__init), std::ref(__f)).value; } template > _Fp> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Rp&& __r, _Tp __init, _Fp __f) { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Rp&& __r, _Tp __init, _Fp __f) { return fold_left_with_iter(ranges::begin(__r), ranges::end(__r), std::move(__init), std::ref(__f)).value; } }; diff --git a/libcxx/include/__algorithm/includes.h b/libcxx/include/__algorithm/includes.h index 05d45365eb80..62af03c37426 100644 --- a/libcxx/include/__algorithm/includes.h +++ b/libcxx/include/__algorithm/includes.h @@ -47,7 +47,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __includes( } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, @@ -67,7 +67,7 @@ includes(_InputIterator1 __first1, } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) { return std::includes(std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __less<>()); } diff --git a/libcxx/include/__algorithm/is_heap.h b/libcxx/include/__algorithm/is_heap.h index 0d2d43c2c3ab..c589b804a5dc 100644 --- a/libcxx/include/__algorithm/is_heap.h +++ b/libcxx/include/__algorithm/is_heap.h @@ -22,13 +22,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { return std::__is_heap_until(__first, __last, static_cast<__comp_ref_type<_Compare> >(__comp)) == __last; } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { return std::is_heap(__first, __last, __less<>()); } diff --git a/libcxx/include/__algorithm/is_heap_until.h b/libcxx/include/__algorithm/is_heap_until.h index 1eae3b86b90d..a174f2453cfc 100644 --- a/libcxx/include/__algorithm/is_heap_until.h +++ b/libcxx/include/__algorithm/is_heap_until.h @@ -46,13 +46,13 @@ __is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Co } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { return std::__is_heap_until(__first, __last, static_cast<__comp_ref_type<_Compare> >(__comp)); } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last) { return std::__is_heap_until(__first, __last, __less<>()); } diff --git a/libcxx/include/__algorithm/is_partitioned.h b/libcxx/include/__algorithm/is_partitioned.h index 71feed332060..1f7c8b0b267e 100644 --- a/libcxx/include/__algorithm/is_partitioned.h +++ b/libcxx/include/__algorithm/is_partitioned.h @@ -18,7 +18,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool is_partitioned(_InputIterator __first, _InputIterator __last, _Predicate __pred) { for (; __first != __last; ++__first) if (!__pred(*__first)) diff --git a/libcxx/include/__algorithm/is_permutation.h b/libcxx/include/__algorithm/is_permutation.h index 4226151222bb..2ddfb32a212b 100644 --- a/libcxx/include/__algorithm/is_permutation.h +++ b/libcxx/include/__algorithm/is_permutation.h @@ -113,7 +113,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __is_permutation_impl( // 2+1 iterators, predicate. Not used by range algorithms. template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __is_permutation( +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __is_permutation( _ForwardIterator1 __first1, _Sentinel1 __last1, _ForwardIterator2 __first2, _BinaryPredicate&& __pred) { // Shorten sequences as much as possible by lopping of any equal prefix. for (; __first1 != __last1; ++__first1, (void)++__first2) { @@ -247,7 +247,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __is_permutation( // 2+1 iterators, predicate template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool is_permutation( +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool is_permutation( _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _BinaryPredicate __pred) { static_assert(__is_callable<_BinaryPredicate, decltype(*__first1), decltype(*__first2)>::value, "The predicate has to be callable"); @@ -257,7 +257,7 @@ _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool i // 2+1 iterators template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) { return std::is_permutation(__first1, __last1, __first2, __equal_to()); } @@ -266,7 +266,7 @@ is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIt // 2+2 iterators template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool is_permutation( +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool is_permutation( _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) { return std::__is_permutation<_ClassicAlgPolicy>( std::move(__first1), @@ -280,7 +280,7 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 // 2+2 iterators, predicate template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool is_permutation( +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool is_permutation( _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, diff --git a/libcxx/include/__algorithm/is_sorted.h b/libcxx/include/__algorithm/is_sorted.h index 1874cace882c..3befb1ac9c26 100644 --- a/libcxx/include/__algorithm/is_sorted.h +++ b/libcxx/include/__algorithm/is_sorted.h @@ -22,13 +22,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool is_sorted(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { return std::__is_sorted_until<__comp_ref_type<_Compare> >(__first, __last, __comp) == __last; } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool is_sorted(_ForwardIterator __first, _ForwardIterator __last) { return std::is_sorted(__first, __last, __less<>()); } diff --git a/libcxx/include/__algorithm/is_sorted_until.h b/libcxx/include/__algorithm/is_sorted_until.h index 7450440df2d8..53a49f00de31 100644 --- a/libcxx/include/__algorithm/is_sorted_until.h +++ b/libcxx/include/__algorithm/is_sorted_until.h @@ -35,13 +35,13 @@ __is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, _Compare __ } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { return std::__is_sorted_until<__comp_ref_type<_Compare> >(__first, __last, __comp); } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator is_sorted_until(_ForwardIterator __first, _ForwardIterator __last) { return std::is_sorted_until(__first, __last, __less<>()); } diff --git a/libcxx/include/__algorithm/lexicographical_compare.h b/libcxx/include/__algorithm/lexicographical_compare.h index 3efd8e24bf6c..edc29e269c88 100644 --- a/libcxx/include/__algorithm/lexicographical_compare.h +++ b/libcxx/include/__algorithm/lexicographical_compare.h @@ -37,7 +37,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __lexicographical_compa } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool lexicographical_compare( +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool lexicographical_compare( _InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, @@ -47,7 +47,7 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool lexicographical_compare( +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool lexicographical_compare( _InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) { return std::lexicographical_compare(__first1, __last1, __first2, __last2, __less<>()); } diff --git a/libcxx/include/__algorithm/lexicographical_compare_three_way.h b/libcxx/include/__algorithm/lexicographical_compare_three_way.h index 50ebdc647a97..a5872e90cf8d 100644 --- a/libcxx/include/__algorithm/lexicographical_compare_three_way.h +++ b/libcxx/include/__algorithm/lexicographical_compare_three_way.h @@ -90,7 +90,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr auto __lexicographical_compare_three_way_slow_pa } template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto lexicographical_compare_three_way( +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto lexicographical_compare_three_way( _InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _Cmp __comp) -> decltype(__comp(*__first1, *__first2)) { static_assert(__comparison_category, @@ -110,7 +110,7 @@ _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto lexicographical_compa } template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto lexicographical_compare_three_way( +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto lexicographical_compare_three_way( _InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) { return std::lexicographical_compare_three_way( std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), std::compare_three_way()); diff --git a/libcxx/include/__algorithm/lower_bound.h b/libcxx/include/__algorithm/lower_bound.h index 8f57f3592c4b..8fd355a7cfc4 100644 --- a/libcxx/include/__algorithm/lower_bound.h +++ b/libcxx/include/__algorithm/lower_bound.h @@ -47,7 +47,7 @@ __lower_bound(_Iter __first, _Sent __last, const _Type& __value, _Comp& __comp, } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) { static_assert(__is_callable<_Compare, decltype(*__first), const _Tp&>::value, "The comparator has to be callable"); auto __proj = std::__identity(); @@ -55,7 +55,7 @@ lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __valu } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { return std::lower_bound(__first, __last, __value, __less<>()); } diff --git a/libcxx/include/__algorithm/max.h b/libcxx/include/__algorithm/max.h index 8171677f155c..d4c99f6f3643 100644 --- a/libcxx/include/__algorithm/max.h +++ b/libcxx/include/__algorithm/max.h @@ -25,13 +25,13 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp& +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp& max(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b, _Compare __comp) { return __comp(__a, __b) ? __b : __a; } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp& +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp& max(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b) { return std::max(__a, __b, __less<>()); } @@ -39,13 +39,13 @@ max(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b) #ifndef _LIBCPP_CXX03_LANG template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp max(initializer_list<_Tp> __t, _Compare __comp) { return *std::__max_element<__comp_ref_type<_Compare> >(__t.begin(), __t.end(), __comp); } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp max(initializer_list<_Tp> __t) { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp max(initializer_list<_Tp> __t) { return *std::max_element(__t.begin(), __t.end(), __less<>()); } diff --git a/libcxx/include/__algorithm/max_element.h b/libcxx/include/__algorithm/max_element.h index f1d4f1cd0938..c036726cbccd 100644 --- a/libcxx/include/__algorithm/max_element.h +++ b/libcxx/include/__algorithm/max_element.h @@ -35,13 +35,13 @@ __max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { return std::__max_element<__comp_ref_type<_Compare> >(__first, __last, __comp); } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator max_element(_ForwardIterator __first, _ForwardIterator __last) { return std::max_element(__first, __last, __less<>()); } diff --git a/libcxx/include/__algorithm/min.h b/libcxx/include/__algorithm/min.h index 919508486fd5..1bafad8a461e 100644 --- a/libcxx/include/__algorithm/min.h +++ b/libcxx/include/__algorithm/min.h @@ -25,13 +25,13 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp& +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp& min(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b, _Compare __comp) { return __comp(__b, __a) ? __b : __a; } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp& +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp& min(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b) { return std::min(__a, __b, __less<>()); } @@ -39,13 +39,13 @@ min(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b) #ifndef _LIBCPP_CXX03_LANG template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp min(initializer_list<_Tp> __t, _Compare __comp) { return *std::__min_element<__comp_ref_type<_Compare> >(__t.begin(), __t.end(), __comp); } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp min(initializer_list<_Tp> __t) { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp min(initializer_list<_Tp> __t) { return *std::min_element(__t.begin(), __t.end(), __less<>()); } diff --git a/libcxx/include/__algorithm/min_element.h b/libcxx/include/__algorithm/min_element.h index c576d665601d..65f3594d630c 100644 --- a/libcxx/include/__algorithm/min_element.h +++ b/libcxx/include/__algorithm/min_element.h @@ -48,7 +48,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iter __min_element(_Iter __ } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { static_assert( __has_forward_iterator_category<_ForwardIterator>::value, "std::min_element requires a ForwardIterator"); @@ -59,7 +59,7 @@ min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator min_element(_ForwardIterator __first, _ForwardIterator __last) { return std::min_element(__first, __last, __less<>()); } diff --git a/libcxx/include/__algorithm/minmax.h b/libcxx/include/__algorithm/minmax.h index 5227b8857175..9feda2b4c0da 100644 --- a/libcxx/include/__algorithm/minmax.h +++ b/libcxx/include/__algorithm/minmax.h @@ -24,13 +24,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair minmax(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b, _Compare __comp) { return __comp(__b, __a) ? pair(__b, __a) : pair(__a, __b); } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair minmax(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b) { return std::minmax(__a, __b, __less<>()); } @@ -38,7 +38,7 @@ minmax(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __ #ifndef _LIBCPP_CXX03_LANG template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Tp, _Tp> +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Tp, _Tp> minmax(initializer_list<_Tp> __t, _Compare __comp) { static_assert(__is_callable<_Compare, _Tp, _Tp>::value, "The comparator has to be callable"); __identity __proj; @@ -47,7 +47,7 @@ minmax(initializer_list<_Tp> __t, _Compare __comp) { } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Tp, _Tp> +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Tp, _Tp> minmax(initializer_list<_Tp> __t) { return std::minmax(__t, __less<>()); } diff --git a/libcxx/include/__algorithm/minmax_element.h b/libcxx/include/__algorithm/minmax_element.h index ff8cda321cef..43cb23347c34 100644 --- a/libcxx/include/__algorithm/minmax_element.h +++ b/libcxx/include/__algorithm/minmax_element.h @@ -79,7 +79,7 @@ __minmax_element_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) } template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_ForwardIterator, _ForwardIterator> +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_ForwardIterator, _ForwardIterator> minmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { static_assert( __has_forward_iterator_category<_ForwardIterator>::value, "std::minmax_element requires a ForwardIterator"); @@ -90,9 +90,8 @@ minmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __com } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 - pair<_ForwardIterator, _ForwardIterator> - minmax_element(_ForwardIterator __first, _ForwardIterator __last) { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_ForwardIterator, _ForwardIterator> +minmax_element(_ForwardIterator __first, _ForwardIterator __last) { return std::minmax_element(__first, __last, __less<>()); } diff --git a/libcxx/include/__algorithm/mismatch.h b/libcxx/include/__algorithm/mismatch.h index 4ada29eabc47..c2b3f8938f71 100644 --- a/libcxx/include/__algorithm/mismatch.h +++ b/libcxx/include/__algorithm/mismatch.h @@ -122,7 +122,7 @@ __mismatch(_Tp* __first1, _Tp* __last1, _Tp* __first2, _Pred& __pred, _Proj1& __ #endif // _LIBCPP_VECTORIZE_ALGORITHMS template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2> +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2> mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __pred) { __identity __proj; auto __res = std::__mismatch( @@ -131,14 +131,14 @@ mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __fi } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2> +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2> mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2) { return std::mismatch(__first1, __last1, __first2, __equal_to()); } #if _LIBCPP_STD_VER >= 14 template -[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_Iter1, _Iter2> __mismatch( +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_Iter1, _Iter2> __mismatch( _Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) { while (__first1 != __last1 && __first2 != __last2) { if (!std::__invoke(__pred, std::__invoke(__proj1, *__first1), std::__invoke(__proj2, *__first2))) @@ -150,14 +150,14 @@ template -[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_Tp*, _Tp*> +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_Tp*, _Tp*> __mismatch(_Tp* __first1, _Tp* __last1, _Tp* __first2, _Tp* __last2, _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) { auto __len = std::min(__last1 - __first1, __last2 - __first2); return std::__mismatch(__first1, __first1 + __len, __first2, __pred, __proj1, __proj2); } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2> +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2> mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, @@ -176,7 +176,7 @@ mismatch(_InputIterator1 __first1, } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2> +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2> mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) { return std::mismatch(__first1, __last1, __first2, __last2, __equal_to()); } diff --git a/libcxx/include/__algorithm/none_of.h b/libcxx/include/__algorithm/none_of.h index ce59187a3a65..50841ba17cc6 100644 --- a/libcxx/include/__algorithm/none_of.h +++ b/libcxx/include/__algorithm/none_of.h @@ -19,7 +19,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool none_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) { for (; __first != __last; ++__first) if (__pred(*__first)) diff --git a/libcxx/include/__algorithm/pstl_any_all_none_of.h b/libcxx/include/__algorithm/pstl_any_all_none_of.h index 911a7e42b3fa..e27463dab8a3 100644 --- a/libcxx/include/__algorithm/pstl_any_all_none_of.h +++ b/libcxx/include/__algorithm/pstl_any_all_none_of.h @@ -58,7 +58,7 @@ template , enable_if_t, int> = 0> -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool any_of(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "any_of requires a ForwardIterator"); auto __res = std::__any_of(__policy, std::move(__first), std::move(__last), std::move(__pred)); @@ -97,7 +97,7 @@ template , enable_if_t, int> = 0> -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool all_of(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred __pred) { _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "all_of requires a ForwardIterator"); auto __res = std::__all_of(__policy, std::move(__first), std::move(__last), std::move(__pred)); @@ -134,7 +134,7 @@ template , enable_if_t, int> = 0> -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool none_of(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred __pred) { _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "none_of requires a ForwardIterator"); auto __res = std::__none_of(__policy, std::move(__first), std::move(__last), std::move(__pred)); diff --git a/libcxx/include/__algorithm/pstl_is_partitioned.h b/libcxx/include/__algorithm/pstl_is_partitioned.h index c016b388e378..2dd5cf3ca2a2 100644 --- a/libcxx/include/__algorithm/pstl_is_partitioned.h +++ b/libcxx/include/__algorithm/pstl_is_partitioned.h @@ -61,7 +61,7 @@ template , enable_if_t, int> = 0> -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI bool is_partitioned(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "is_partitioned requires ForwardIterators"); auto __res = std::__is_partitioned(__policy, std::move(__first), std::move(__last), std::move(__pred)); diff --git a/libcxx/include/__algorithm/ranges_adjacent_find.h b/libcxx/include/__algorithm/ranges_adjacent_find.h index a10b04167ede..3c54f723310a 100644 --- a/libcxx/include/__algorithm/ranges_adjacent_find.h +++ b/libcxx/include/__algorithm/ranges_adjacent_find.h @@ -53,7 +53,7 @@ struct __fn { sentinel_for<_Iter> _Sent, class _Proj = identity, indirect_binary_predicate, projected<_Iter, _Proj>> _Pred = ranges::equal_to> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Iter + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Iter operator()(_Iter __first, _Sent __last, _Pred __pred = {}, _Proj __proj = {}) const { return __adjacent_find_impl(std::move(__first), std::move(__last), __pred, __proj); } @@ -62,7 +62,7 @@ struct __fn { class _Proj = identity, indirect_binary_predicate, _Proj>, projected, _Proj>> _Pred = ranges::equal_to> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> operator()(_Range&& __range, _Pred __pred = {}, _Proj __proj = {}) const { return __adjacent_find_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); } diff --git a/libcxx/include/__algorithm/ranges_all_of.h b/libcxx/include/__algorithm/ranges_all_of.h index 8976541d590c..2f603b32f32d 100644 --- a/libcxx/include/__algorithm/ranges_all_of.h +++ b/libcxx/include/__algorithm/ranges_all_of.h @@ -45,7 +45,7 @@ struct __fn { sentinel_for<_Iter> _Sent, class _Proj = identity, indirect_unary_predicate> _Pred> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { return __all_of_impl(std::move(__first), std::move(__last), __pred, __proj); } @@ -53,7 +53,7 @@ struct __fn { template , _Proj>> _Pred> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { return __all_of_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); } diff --git a/libcxx/include/__algorithm/ranges_any_of.h b/libcxx/include/__algorithm/ranges_any_of.h index 7c775f5f64de..205fcecc086e 100644 --- a/libcxx/include/__algorithm/ranges_any_of.h +++ b/libcxx/include/__algorithm/ranges_any_of.h @@ -45,7 +45,7 @@ struct __fn { sentinel_for<_Iter> _Sent, class _Proj = identity, indirect_unary_predicate> _Pred> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Iter __first, _Sent __last, _Pred __pred = {}, _Proj __proj = {}) const { return __any_of_impl(std::move(__first), std::move(__last), __pred, __proj); } @@ -53,7 +53,7 @@ struct __fn { template , _Proj>> _Pred> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { return __any_of_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); } diff --git a/libcxx/include/__algorithm/ranges_binary_search.h b/libcxx/include/__algorithm/ranges_binary_search.h index f3b7842d5ccc..1ef2bd62b599 100644 --- a/libcxx/include/__algorithm/ranges_binary_search.h +++ b/libcxx/include/__algorithm/ranges_binary_search.h @@ -39,7 +39,7 @@ struct __fn { class _Type, class _Proj = identity, indirect_strict_weak_order> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Iter __first, _Sent __last, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const { auto __ret = std::__lower_bound<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj); return __ret != __last && !std::invoke(__comp, __value, std::invoke(__proj, *__ret)); @@ -49,7 +49,7 @@ struct __fn { class _Type, class _Proj = identity, indirect_strict_weak_order, _Proj>> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Range&& __r, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const { auto __first = ranges::begin(__r); auto __last = ranges::end(__r); diff --git a/libcxx/include/__algorithm/ranges_clamp.h b/libcxx/include/__algorithm/ranges_clamp.h index f5ef5fd7f26e..e6181ef9435e 100644 --- a/libcxx/include/__algorithm/ranges_clamp.h +++ b/libcxx/include/__algorithm/ranges_clamp.h @@ -35,7 +35,7 @@ struct __fn { template > _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr const _Type& operator()( + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const _Type& operator()( const _Type& __value, const _Type& __low, const _Type& __high, _Comp __comp = {}, _Proj __proj = {}) const { _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN( !bool(std::invoke(__comp, std::invoke(__proj, __high), std::invoke(__proj, __low))), diff --git a/libcxx/include/__algorithm/ranges_contains.h b/libcxx/include/__algorithm/ranges_contains.h index 00d0e5401988..4836c3baed17 100644 --- a/libcxx/include/__algorithm/ranges_contains.h +++ b/libcxx/include/__algorithm/ranges_contains.h @@ -37,14 +37,14 @@ namespace __contains { struct __fn { template _Sent, class _Type, class _Proj = identity> requires indirect_binary_predicate, const _Type*> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool static + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool static operator()(_Iter __first, _Sent __last, const _Type& __value, _Proj __proj = {}) { return ranges::find(std::move(__first), __last, __value, std::ref(__proj)) != __last; } template requires indirect_binary_predicate, _Proj>, const _Type*> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool static + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool static operator()(_Range&& __range, const _Type& __value, _Proj __proj = {}) { return ranges::find(ranges::begin(__range), ranges::end(__range), __value, std::ref(__proj)) != ranges::end(__range); diff --git a/libcxx/include/__algorithm/ranges_contains_subrange.h b/libcxx/include/__algorithm/ranges_contains_subrange.h index bc5a86ce3d69..4398c457fd05 100644 --- a/libcxx/include/__algorithm/ranges_contains_subrange.h +++ b/libcxx/include/__algorithm/ranges_contains_subrange.h @@ -45,7 +45,7 @@ struct __fn { class _Proj1 = identity, class _Proj2 = identity> requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool static operator()( + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool static operator()( _Iter1 __first1, _Sent1 __last1, _Iter2 __first2, @@ -67,7 +67,7 @@ struct __fn { class _Proj1 = identity, class _Proj2 = identity> requires indirectly_comparable, iterator_t<_Range2>, _Pred, _Proj1, _Proj2> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool static + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool static operator()(_Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) { if constexpr (sized_range<_Range2>) { if (ranges::size(__range2) == 0) diff --git a/libcxx/include/__algorithm/ranges_count.h b/libcxx/include/__algorithm/ranges_count.h index a8965c1b961f..4f3511743870 100644 --- a/libcxx/include/__algorithm/ranges_count.h +++ b/libcxx/include/__algorithm/ranges_count.h @@ -38,14 +38,14 @@ namespace __count { struct __fn { template _Sent, class _Type, class _Proj = identity> requires indirect_binary_predicate, const _Type*> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Iter> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Iter> operator()(_Iter __first, _Sent __last, const _Type& __value, _Proj __proj = {}) const { return std::__count<_RangeAlgPolicy>(std::move(__first), std::move(__last), __value, __proj); } template requires indirect_binary_predicate, _Proj>, const _Type*> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr range_difference_t<_Range> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr range_difference_t<_Range> operator()(_Range&& __r, const _Type& __value, _Proj __proj = {}) const { return std::__count<_RangeAlgPolicy>(ranges::begin(__r), ranges::end(__r), __value, __proj); } diff --git a/libcxx/include/__algorithm/ranges_count_if.h b/libcxx/include/__algorithm/ranges_count_if.h index 71b942dd5322..5f2396ff7d53 100644 --- a/libcxx/include/__algorithm/ranges_count_if.h +++ b/libcxx/include/__algorithm/ranges_count_if.h @@ -50,7 +50,7 @@ struct __fn { sentinel_for<_Iter> _Sent, class _Proj = identity, indirect_unary_predicate> _Predicate> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Iter> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Iter> operator()(_Iter __first, _Sent __last, _Predicate __pred, _Proj __proj = {}) const { return ranges::__count_if_impl(std::move(__first), std::move(__last), __pred, __proj); } @@ -58,7 +58,7 @@ struct __fn { template , _Proj>> _Predicate> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr range_difference_t<_Range> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr range_difference_t<_Range> operator()(_Range&& __r, _Predicate __pred, _Proj __proj = {}) const { return ranges::__count_if_impl(ranges::begin(__r), ranges::end(__r), __pred, __proj); } diff --git a/libcxx/include/__algorithm/ranges_ends_with.h b/libcxx/include/__algorithm/ranges_ends_with.h index bb01918326b8..06efdef36b7c 100644 --- a/libcxx/include/__algorithm/ranges_ends_with.h +++ b/libcxx/include/__algorithm/ranges_ends_with.h @@ -133,7 +133,7 @@ struct __fn { requires(forward_iterator<_Iter1> || sized_sentinel_for<_Sent1, _Iter1>) && (forward_iterator<_Iter2> || sized_sentinel_for<_Sent2, _Iter2>) && indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( _Iter1 __first1, _Sent1 __last1, _Iter2 __first2, @@ -152,7 +152,7 @@ struct __fn { class _Proj2 = identity> requires(forward_range<_Range1> || sized_range<_Range1>) && (forward_range<_Range2> || sized_range<_Range2>) && indirectly_comparable, iterator_t<_Range2>, _Pred, _Proj1, _Proj2> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( _Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { if constexpr (sized_range<_Range1> && sized_range<_Range2>) { auto __n1 = ranges::size(__range1); diff --git a/libcxx/include/__algorithm/ranges_equal.h b/libcxx/include/__algorithm/ranges_equal.h index 31c7ee261da6..edbd0e3641c1 100644 --- a/libcxx/include/__algorithm/ranges_equal.h +++ b/libcxx/include/__algorithm/ranges_equal.h @@ -44,7 +44,7 @@ struct __fn { class _Proj1 = identity, class _Proj2 = identity> requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( _Iter1 __first1, _Sent1 __last1, _Iter2 __first2, @@ -74,7 +74,7 @@ struct __fn { class _Proj1 = identity, class _Proj2 = identity> requires indirectly_comparable, iterator_t<_Range2>, _Pred, _Proj1, _Proj2> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( _Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { if constexpr (sized_range<_Range1> && sized_range<_Range2>) { if (ranges::distance(__range1) != ranges::distance(__range2)) diff --git a/libcxx/include/__algorithm/ranges_equal_range.h b/libcxx/include/__algorithm/ranges_equal_range.h index 4c1c3834ba9f..4a308e016b54 100644 --- a/libcxx/include/__algorithm/ranges_equal_range.h +++ b/libcxx/include/__algorithm/ranges_equal_range.h @@ -46,7 +46,7 @@ struct __fn { class _Tp, class _Proj = identity, indirect_strict_weak_order> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter> operator()(_Iter __first, _Sent __last, const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const { auto __ret = std::__equal_range<_RangeAlgPolicy>(std::move(__first), std::move(__last), __value, __comp, __proj); return {std::move(__ret.first), std::move(__ret.second)}; @@ -56,7 +56,7 @@ struct __fn { class _Tp, class _Proj = identity, indirect_strict_weak_order, _Proj>> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range> operator()(_Range&& __range, const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const { auto __ret = std::__equal_range<_RangeAlgPolicy>(ranges::begin(__range), ranges::end(__range), __value, __comp, __proj); diff --git a/libcxx/include/__algorithm/ranges_find.h b/libcxx/include/__algorithm/ranges_find.h index 7459fad717a5..e1383eb4b071 100644 --- a/libcxx/include/__algorithm/ranges_find.h +++ b/libcxx/include/__algorithm/ranges_find.h @@ -52,14 +52,14 @@ struct __fn { template _Sp, class _Tp, class _Proj = identity> requires indirect_binary_predicate, const _Tp*> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Ip + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Ip operator()(_Ip __first, _Sp __last, const _Tp& __value, _Proj __proj = {}) const { return __find_unwrap(std::move(__first), std::move(__last), __value, __proj); } template requires indirect_binary_predicate, _Proj>, const _Tp*> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Rp> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Rp> operator()(_Rp&& __r, const _Tp& __value, _Proj __proj = {}) const { return __find_unwrap(ranges::begin(__r), ranges::end(__r), __value, __proj); } diff --git a/libcxx/include/__algorithm/ranges_find_end.h b/libcxx/include/__algorithm/ranges_find_end.h index 0bda4f3e1cea..e49e66dd4ac0 100644 --- a/libcxx/include/__algorithm/ranges_find_end.h +++ b/libcxx/include/__algorithm/ranges_find_end.h @@ -45,7 +45,7 @@ struct __fn { class _Proj1 = identity, class _Proj2 = identity> requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter1> operator()( + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter1> operator()( _Iter1 __first1, _Sent1 __last1, _Iter2 __first2, @@ -72,7 +72,7 @@ struct __fn { class _Proj1 = identity, class _Proj2 = identity> requires indirectly_comparable, iterator_t<_Range2>, _Pred, _Proj1, _Proj2> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range1> operator()( + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range1> operator()( _Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { auto __ret = std::__find_end_impl<_RangeAlgPolicy>( ranges::begin(__range1), diff --git a/libcxx/include/__algorithm/ranges_find_first_of.h b/libcxx/include/__algorithm/ranges_find_first_of.h index 63a7b8335faa..d92d9686bc44 100644 --- a/libcxx/include/__algorithm/ranges_find_first_of.h +++ b/libcxx/include/__algorithm/ranges_find_first_of.h @@ -60,7 +60,7 @@ struct __fn { class _Proj1 = identity, class _Proj2 = identity> requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Iter1 operator()( + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Iter1 operator()( _Iter1 __first1, _Sent1 __last1, _Iter2 __first2, @@ -78,7 +78,7 @@ struct __fn { class _Proj1 = identity, class _Proj2 = identity> requires indirectly_comparable, iterator_t<_Range2>, _Pred, _Proj1, _Proj2> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range1> operator()( + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range1> operator()( _Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { return __find_first_of_impl( ranges::begin(__range1), diff --git a/libcxx/include/__algorithm/ranges_find_if.h b/libcxx/include/__algorithm/ranges_find_if.h index 52ae55ce96c3..888f9ec3cb2d 100644 --- a/libcxx/include/__algorithm/ranges_find_if.h +++ b/libcxx/include/__algorithm/ranges_find_if.h @@ -48,13 +48,13 @@ struct __fn { sentinel_for<_Ip> _Sp, class _Proj = identity, indirect_unary_predicate> _Pred> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Ip + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Ip operator()(_Ip __first, _Sp __last, _Pred __pred, _Proj __proj = {}) const { return ranges::__find_if_impl(std::move(__first), std::move(__last), __pred, __proj); } template , _Proj>> _Pred> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Rp> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Rp> operator()(_Rp&& __r, _Pred __pred, _Proj __proj = {}) const { return ranges::__find_if_impl(ranges::begin(__r), ranges::end(__r), __pred, __proj); } diff --git a/libcxx/include/__algorithm/ranges_find_if_not.h b/libcxx/include/__algorithm/ranges_find_if_not.h index 60c6796cbbfc..ec19545b5a1b 100644 --- a/libcxx/include/__algorithm/ranges_find_if_not.h +++ b/libcxx/include/__algorithm/ranges_find_if_not.h @@ -40,14 +40,14 @@ struct __fn { sentinel_for<_Ip> _Sp, class _Proj = identity, indirect_unary_predicate> _Pred> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Ip + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Ip operator()(_Ip __first, _Sp __last, _Pred __pred, _Proj __proj = {}) const { auto __pred2 = [&](auto&& __e) -> bool { return !std::invoke(__pred, std::forward(__e)); }; return ranges::__find_if_impl(std::move(__first), std::move(__last), __pred2, __proj); } template , _Proj>> _Pred> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Rp> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Rp> operator()(_Rp&& __r, _Pred __pred, _Proj __proj = {}) const { auto __pred2 = [&](auto&& __e) -> bool { return !std::invoke(__pred, std::forward(__e)); }; return ranges::__find_if_impl(ranges::begin(__r), ranges::end(__r), __pred2, __proj); diff --git a/libcxx/include/__algorithm/ranges_includes.h b/libcxx/include/__algorithm/ranges_includes.h index 0bc4c043bd18..c4c3b8ed088d 100644 --- a/libcxx/include/__algorithm/ranges_includes.h +++ b/libcxx/include/__algorithm/ranges_includes.h @@ -45,7 +45,7 @@ struct __fn { class _Proj1 = identity, class _Proj2 = identity, indirect_strict_weak_order, projected<_Iter2, _Proj2>> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( _Iter1 __first1, _Sent1 __last1, _Iter2 __first2, @@ -69,7 +69,7 @@ struct __fn { class _Proj2 = identity, indirect_strict_weak_order, _Proj1>, projected, _Proj2>> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( _Range1&& __range1, _Range2&& __range2, _Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { return std::__includes( ranges::begin(__range1), diff --git a/libcxx/include/__algorithm/ranges_is_heap.h b/libcxx/include/__algorithm/ranges_is_heap.h index 122368c90d92..3d9e18ce1d90 100644 --- a/libcxx/include/__algorithm/ranges_is_heap.h +++ b/libcxx/include/__algorithm/ranges_is_heap.h @@ -51,7 +51,7 @@ struct __fn { sentinel_for<_Iter> _Sent, class _Proj = identity, indirect_strict_weak_order> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { return __is_heap_fn_impl(std::move(__first), std::move(__last), __comp, __proj); } @@ -59,7 +59,7 @@ struct __fn { template , _Proj>> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const { return __is_heap_fn_impl(ranges::begin(__range), ranges::end(__range), __comp, __proj); } diff --git a/libcxx/include/__algorithm/ranges_is_heap_until.h b/libcxx/include/__algorithm/ranges_is_heap_until.h index b2705d37a6d3..7a2e1fc7705b 100644 --- a/libcxx/include/__algorithm/ranges_is_heap_until.h +++ b/libcxx/include/__algorithm/ranges_is_heap_until.h @@ -51,7 +51,7 @@ struct __fn { sentinel_for<_Iter> _Sent, class _Proj = identity, indirect_strict_weak_order> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Iter + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { return __is_heap_until_fn_impl(std::move(__first), std::move(__last), __comp, __proj); } @@ -59,7 +59,7 @@ struct __fn { template , _Proj>> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const { return __is_heap_until_fn_impl(ranges::begin(__range), ranges::end(__range), __comp, __proj); } diff --git a/libcxx/include/__algorithm/ranges_is_partitioned.h b/libcxx/include/__algorithm/ranges_is_partitioned.h index c6a585c9f510..5be6fba46fd9 100644 --- a/libcxx/include/__algorithm/ranges_is_partitioned.h +++ b/libcxx/include/__algorithm/ranges_is_partitioned.h @@ -57,7 +57,7 @@ struct __fn { sentinel_for<_Iter> _Sent, class _Proj = identity, indirect_unary_predicate> _Pred> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { return __is_partitioned_impl(std::move(__first), std::move(__last), __pred, __proj); } @@ -65,7 +65,7 @@ struct __fn { template , _Proj>> _Pred> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { return __is_partitioned_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); } diff --git a/libcxx/include/__algorithm/ranges_is_permutation.h b/libcxx/include/__algorithm/ranges_is_permutation.h index e0423d722b5b..1f8d67007a57 100644 --- a/libcxx/include/__algorithm/ranges_is_permutation.h +++ b/libcxx/include/__algorithm/ranges_is_permutation.h @@ -56,7 +56,7 @@ struct __fn { class _Proj1 = identity, class _Proj2 = identity, indirect_equivalence_relation, projected<_Iter2, _Proj2>> _Pred = ranges::equal_to> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( _Iter1 __first1, _Sent1 __last1, _Iter2 __first2, @@ -74,7 +74,7 @@ struct __fn { class _Proj2 = identity, indirect_equivalence_relation, _Proj1>, projected, _Proj2>> _Pred = ranges::equal_to> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( _Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { if constexpr (sized_range<_Range1> && sized_range<_Range2>) { if (ranges::distance(__range1) != ranges::distance(__range2)) diff --git a/libcxx/include/__algorithm/ranges_is_sorted.h b/libcxx/include/__algorithm/ranges_is_sorted.h index d71035d5aa1d..5b88d422b4b0 100644 --- a/libcxx/include/__algorithm/ranges_is_sorted.h +++ b/libcxx/include/__algorithm/ranges_is_sorted.h @@ -37,7 +37,7 @@ struct __fn { sentinel_for<_Iter> _Sent, class _Proj = identity, indirect_strict_weak_order> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { return ranges::__is_sorted_until_impl(std::move(__first), __last, __comp, __proj) == __last; } @@ -45,7 +45,7 @@ struct __fn { template , _Proj>> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const { auto __last = ranges::end(__range); return ranges::__is_sorted_until_impl(ranges::begin(__range), __last, __comp, __proj) == __last; diff --git a/libcxx/include/__algorithm/ranges_is_sorted_until.h b/libcxx/include/__algorithm/ranges_is_sorted_until.h index dcfb6a4e1813..54de530c8b2f 100644 --- a/libcxx/include/__algorithm/ranges_is_sorted_until.h +++ b/libcxx/include/__algorithm/ranges_is_sorted_until.h @@ -53,7 +53,7 @@ struct __fn { sentinel_for<_Iter> _Sent, class _Proj = identity, indirect_strict_weak_order> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Iter + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { return ranges::__is_sorted_until_impl(std::move(__first), std::move(__last), __comp, __proj); } @@ -61,7 +61,7 @@ struct __fn { template , _Proj>> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const { return ranges::__is_sorted_until_impl(ranges::begin(__range), ranges::end(__range), __comp, __proj); } diff --git a/libcxx/include/__algorithm/ranges_lexicographical_compare.h b/libcxx/include/__algorithm/ranges_lexicographical_compare.h index 90e96b546516..6d82017e302a 100644 --- a/libcxx/include/__algorithm/ranges_lexicographical_compare.h +++ b/libcxx/include/__algorithm/ranges_lexicographical_compare.h @@ -60,7 +60,7 @@ struct __fn { class _Proj1 = identity, class _Proj2 = identity, indirect_strict_weak_order, projected<_Iter2, _Proj2>> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( _Iter1 __first1, _Sent1 __last1, _Iter2 __first2, @@ -78,7 +78,7 @@ struct __fn { class _Proj2 = identity, indirect_strict_weak_order, _Proj1>, projected, _Proj2>> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( _Range1&& __range1, _Range2&& __range2, _Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { return __lexicographical_compare_impl( ranges::begin(__range1), diff --git a/libcxx/include/__algorithm/ranges_lower_bound.h b/libcxx/include/__algorithm/ranges_lower_bound.h index ab1f80e7ab77..0651147e0424 100644 --- a/libcxx/include/__algorithm/ranges_lower_bound.h +++ b/libcxx/include/__algorithm/ranges_lower_bound.h @@ -43,7 +43,7 @@ struct __fn { class _Type, class _Proj = identity, indirect_strict_weak_order> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Iter + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Iter operator()(_Iter __first, _Sent __last, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const { return std::__lower_bound<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj); } @@ -52,7 +52,7 @@ struct __fn { class _Type, class _Proj = identity, indirect_strict_weak_order, _Proj>> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> operator()(_Range&& __r, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const { return std::__lower_bound<_RangeAlgPolicy>(ranges::begin(__r), ranges::end(__r), __value, __comp, __proj); } diff --git a/libcxx/include/__algorithm/ranges_max.h b/libcxx/include/__algorithm/ranges_max.h index c63656de5134..d0ee6f314b0c 100644 --- a/libcxx/include/__algorithm/ranges_max.h +++ b/libcxx/include/__algorithm/ranges_max.h @@ -41,7 +41,7 @@ struct __fn { template > _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator()(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b, _Comp __comp = {}, @@ -52,7 +52,7 @@ struct __fn { template > _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Tp + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp operator()(initializer_list<_Tp> __il, _Comp __comp = {}, _Proj __proj = {}) const { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( __il.begin() != __il.end(), "initializer_list must contain at least one element"); @@ -65,7 +65,7 @@ struct __fn { class _Proj = identity, indirect_strict_weak_order, _Proj>> _Comp = ranges::less> requires indirectly_copyable_storable, range_value_t<_Rp>*> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr range_value_t<_Rp> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr range_value_t<_Rp> operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const { auto __first = ranges::begin(__r); auto __last = ranges::end(__r); diff --git a/libcxx/include/__algorithm/ranges_max_element.h b/libcxx/include/__algorithm/ranges_max_element.h index 83adf49b61ad..c57730927116 100644 --- a/libcxx/include/__algorithm/ranges_max_element.h +++ b/libcxx/include/__algorithm/ranges_max_element.h @@ -38,7 +38,7 @@ struct __fn { sentinel_for<_Ip> _Sp, class _Proj = identity, indirect_strict_weak_order> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Ip + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Ip operator()(_Ip __first, _Sp __last, _Comp __comp = {}, _Proj __proj = {}) const { auto __comp_lhs_rhs_swapped = [&](auto&& __lhs, auto&& __rhs) -> bool { return std::invoke(__comp, __rhs, __lhs); }; return ranges::__min_element_impl(__first, __last, __comp_lhs_rhs_swapped, __proj); @@ -47,7 +47,7 @@ struct __fn { template , _Proj>> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Rp> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Rp> operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const { auto __comp_lhs_rhs_swapped = [&](auto&& __lhs, auto&& __rhs) -> bool { return std::invoke(__comp, __rhs, __lhs); }; return ranges::__min_element_impl(ranges::begin(__r), ranges::end(__r), __comp_lhs_rhs_swapped, __proj); diff --git a/libcxx/include/__algorithm/ranges_min.h b/libcxx/include/__algorithm/ranges_min.h index e8f97f2754ac..cc569d2a060c 100644 --- a/libcxx/include/__algorithm/ranges_min.h +++ b/libcxx/include/__algorithm/ranges_min.h @@ -40,7 +40,7 @@ struct __fn { template > _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator()(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b, _Comp __comp = {}, @@ -51,7 +51,7 @@ struct __fn { template > _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Tp + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp operator()(initializer_list<_Tp> __il, _Comp __comp = {}, _Proj __proj = {}) const { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( __il.begin() != __il.end(), "initializer_list must contain at least one element"); @@ -62,7 +62,7 @@ struct __fn { class _Proj = identity, indirect_strict_weak_order, _Proj>> _Comp = ranges::less> requires indirectly_copyable_storable, range_value_t<_Rp>*> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr range_value_t<_Rp> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr range_value_t<_Rp> operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const { auto __first = ranges::begin(__r); auto __last = ranges::end(__r); diff --git a/libcxx/include/__algorithm/ranges_min_element.h b/libcxx/include/__algorithm/ranges_min_element.h index 4b9cb76da578..588ef258e26f 100644 --- a/libcxx/include/__algorithm/ranges_min_element.h +++ b/libcxx/include/__algorithm/ranges_min_element.h @@ -52,7 +52,7 @@ struct __fn { sentinel_for<_Ip> _Sp, class _Proj = identity, indirect_strict_weak_order> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Ip + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Ip operator()(_Ip __first, _Sp __last, _Comp __comp = {}, _Proj __proj = {}) const { return ranges::__min_element_impl(__first, __last, __comp, __proj); } @@ -60,7 +60,7 @@ struct __fn { template , _Proj>> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Rp> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Rp> operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const { return ranges::__min_element_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj); } diff --git a/libcxx/include/__algorithm/ranges_minmax.h b/libcxx/include/__algorithm/ranges_minmax.h index ca5722523336..09cbefd91a8c 100644 --- a/libcxx/include/__algorithm/ranges_minmax.h +++ b/libcxx/include/__algorithm/ranges_minmax.h @@ -52,7 +52,7 @@ struct __fn { template > _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr ranges::minmax_result + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr ranges::minmax_result operator()(_LIBCPP_LIFETIMEBOUND const _Type& __a, _LIBCPP_LIFETIMEBOUND const _Type& __b, _Comp __comp = {}, @@ -65,7 +65,7 @@ struct __fn { template > _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr ranges::minmax_result<_Type> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr ranges::minmax_result<_Type> operator()(initializer_list<_Type> __il, _Comp __comp = {}, _Proj __proj = {}) const { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( __il.begin() != __il.end(), "initializer_list has to contain at least one element"); @@ -77,7 +77,7 @@ struct __fn { class _Proj = identity, indirect_strict_weak_order, _Proj>> _Comp = ranges::less> requires indirectly_copyable_storable, range_value_t<_Range>*> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr ranges::minmax_result> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr ranges::minmax_result> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { auto __first = ranges::begin(__r); auto __last = ranges::end(__r); diff --git a/libcxx/include/__algorithm/ranges_minmax_element.h b/libcxx/include/__algorithm/ranges_minmax_element.h index 5132856ebcd5..4bf6d2404e46 100644 --- a/libcxx/include/__algorithm/ranges_minmax_element.h +++ b/libcxx/include/__algorithm/ranges_minmax_element.h @@ -46,7 +46,7 @@ struct __fn { sentinel_for<_Ip> _Sp, class _Proj = identity, indirect_strict_weak_order> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr ranges::minmax_element_result<_Ip> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr ranges::minmax_element_result<_Ip> operator()(_Ip __first, _Sp __last, _Comp __comp = {}, _Proj __proj = {}) const { auto __ret = std::__minmax_element_impl(std::move(__first), std::move(__last), __comp, __proj); return {__ret.first, __ret.second}; @@ -55,7 +55,7 @@ struct __fn { template , _Proj>> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr ranges::minmax_element_result> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr ranges::minmax_element_result> operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const { auto __ret = std::__minmax_element_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj); return {__ret.first, __ret.second}; diff --git a/libcxx/include/__algorithm/ranges_mismatch.h b/libcxx/include/__algorithm/ranges_mismatch.h index d8a7dd43af09..c4bf0022a9bc 100644 --- a/libcxx/include/__algorithm/ranges_mismatch.h +++ b/libcxx/include/__algorithm/ranges_mismatch.h @@ -65,7 +65,7 @@ struct __fn { class _Proj1 = identity, class _Proj2 = identity> requires indirectly_comparable<_I1, _I2, _Pred, _Proj1, _Proj2> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr mismatch_result<_I1, _I2> operator()( + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr mismatch_result<_I1, _I2> operator()( _I1 __first1, _S1 __last1, _I2 __first2, _S2 __last2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { return __go(std::move(__first1), __last1, std::move(__first2), __last2, __pred, __proj1, __proj2); @@ -77,7 +77,7 @@ struct __fn { class _Proj1 = identity, class _Proj2 = identity> requires indirectly_comparable, iterator_t<_R2>, _Pred, _Proj1, _Proj2> - _LIBCPP_NODISCARD_EXT + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr mismatch_result, borrowed_iterator_t<_R2>> operator()(_R1&& __r1, _R2&& __r2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { return __go( diff --git a/libcxx/include/__algorithm/ranges_none_of.h b/libcxx/include/__algorithm/ranges_none_of.h index 59bd87997d44..7df3c1829fcf 100644 --- a/libcxx/include/__algorithm/ranges_none_of.h +++ b/libcxx/include/__algorithm/ranges_none_of.h @@ -46,7 +46,7 @@ struct __fn { sentinel_for<_Iter> _Sent, class _Proj = identity, indirect_unary_predicate> _Pred> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Iter __first, _Sent __last, _Pred __pred = {}, _Proj __proj = {}) const { return __none_of_impl(std::move(__first), std::move(__last), __pred, __proj); } @@ -54,7 +54,7 @@ struct __fn { template , _Proj>> _Pred> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { return __none_of_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); } diff --git a/libcxx/include/__algorithm/ranges_remove.h b/libcxx/include/__algorithm/ranges_remove.h index 315bed8fba77..17c3a2c5cd06 100644 --- a/libcxx/include/__algorithm/ranges_remove.h +++ b/libcxx/include/__algorithm/ranges_remove.h @@ -37,7 +37,7 @@ namespace __remove { struct __fn { template _Sent, class _Type, class _Proj = identity> requires indirect_binary_predicate, const _Type*> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter> operator()(_Iter __first, _Sent __last, const _Type& __value, _Proj __proj = {}) const { auto __pred = [&](auto&& __other) -> bool { return __value == __other; }; return ranges::__remove_if_impl(std::move(__first), std::move(__last), __pred, __proj); @@ -46,7 +46,7 @@ struct __fn { template requires permutable> && indirect_binary_predicate, _Proj>, const _Type*> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range> operator()(_Range&& __range, const _Type& __value, _Proj __proj = {}) const { auto __pred = [&](auto&& __other) -> bool { return __value == __other; }; return ranges::__remove_if_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); diff --git a/libcxx/include/__algorithm/ranges_remove_if.h b/libcxx/include/__algorithm/ranges_remove_if.h index 943dbdd73807..0ea5d9a01b88 100644 --- a/libcxx/include/__algorithm/ranges_remove_if.h +++ b/libcxx/include/__algorithm/ranges_remove_if.h @@ -59,7 +59,7 @@ struct __fn { sentinel_for<_Iter> _Sent, class _Proj = identity, indirect_unary_predicate> _Pred> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter> operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { return ranges::__remove_if_impl(std::move(__first), std::move(__last), __pred, __proj); } @@ -68,7 +68,7 @@ struct __fn { class _Proj = identity, indirect_unary_predicate, _Proj>> _Pred> requires permutable> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range> operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { return ranges::__remove_if_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); } diff --git a/libcxx/include/__algorithm/ranges_search.h b/libcxx/include/__algorithm/ranges_search.h index ca2326e9ab27..55294c60631b 100644 --- a/libcxx/include/__algorithm/ranges_search.h +++ b/libcxx/include/__algorithm/ranges_search.h @@ -77,7 +77,7 @@ struct __fn { class _Proj1 = identity, class _Proj2 = identity> requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter1> operator()( + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter1> operator()( _Iter1 __first1, _Sent1 __last1, _Iter2 __first2, @@ -94,7 +94,7 @@ struct __fn { class _Proj1 = identity, class _Proj2 = identity> requires indirectly_comparable, iterator_t<_Range2>, _Pred, _Proj1, _Proj2> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range1> operator()( + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range1> operator()( _Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { auto __first1 = ranges::begin(__range1); if constexpr (sized_range<_Range2>) { diff --git a/libcxx/include/__algorithm/ranges_search_n.h b/libcxx/include/__algorithm/ranges_search_n.h index 4c1d73d8e6c3..56e12755b9bf 100644 --- a/libcxx/include/__algorithm/ranges_search_n.h +++ b/libcxx/include/__algorithm/ranges_search_n.h @@ -71,7 +71,7 @@ struct __fn { class _Pred = ranges::equal_to, class _Proj = identity> requires indirectly_comparable<_Iter, const _Type*, _Pred, _Proj> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter> operator()(_Iter __first, _Sent __last, iter_difference_t<_Iter> __count, @@ -83,7 +83,7 @@ struct __fn { template requires indirectly_comparable, const _Type*, _Pred, _Proj> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range> operator()( + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range> operator()( _Range&& __range, range_difference_t<_Range> __count, const _Type& __value, _Pred __pred = {}, _Proj __proj = {}) const { auto __first = ranges::begin(__range); diff --git a/libcxx/include/__algorithm/ranges_starts_with.h b/libcxx/include/__algorithm/ranges_starts_with.h index 7ba8af13a8d1..17084e4f2433 100644 --- a/libcxx/include/__algorithm/ranges_starts_with.h +++ b/libcxx/include/__algorithm/ranges_starts_with.h @@ -42,7 +42,7 @@ struct __fn { class _Proj1 = identity, class _Proj2 = identity> requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI static constexpr bool operator()( + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr bool operator()( _Iter1 __first1, _Sent1 __last1, _Iter2 __first2, @@ -67,7 +67,7 @@ struct __fn { class _Proj1 = identity, class _Proj2 = identity> requires indirectly_comparable, iterator_t<_Range2>, _Pred, _Proj1, _Proj2> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI static constexpr bool + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr bool operator()(_Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) { return __mismatch::__fn::__go( ranges::begin(__range1), diff --git a/libcxx/include/__algorithm/ranges_unique.h b/libcxx/include/__algorithm/ranges_unique.h index 7340310eb36a..7a9b78432187 100644 --- a/libcxx/include/__algorithm/ranges_unique.h +++ b/libcxx/include/__algorithm/ranges_unique.h @@ -47,7 +47,7 @@ struct __fn { sentinel_for<_Iter> _Sent, class _Proj = identity, indirect_equivalence_relation> _Comp = ranges::equal_to> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter> operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { auto __ret = std::__unique<_RangeAlgPolicy>(std::move(__first), std::move(__last), std::__make_projected(__comp, __proj)); @@ -58,7 +58,7 @@ struct __fn { class _Proj = identity, indirect_equivalence_relation, _Proj>> _Comp = ranges::equal_to> requires permutable> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range> operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const { auto __ret = std::__unique<_RangeAlgPolicy>( ranges::begin(__range), ranges::end(__range), std::__make_projected(__comp, __proj)); diff --git a/libcxx/include/__algorithm/ranges_upper_bound.h b/libcxx/include/__algorithm/ranges_upper_bound.h index 7b571fb3448f..fa6fa7f70ed5 100644 --- a/libcxx/include/__algorithm/ranges_upper_bound.h +++ b/libcxx/include/__algorithm/ranges_upper_bound.h @@ -37,7 +37,7 @@ struct __fn { class _Type, class _Proj = identity, indirect_strict_weak_order> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Iter + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Iter operator()(_Iter __first, _Sent __last, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const { auto __comp_lhs_rhs_swapped = [&](const auto& __lhs, const auto& __rhs) -> bool { return !std::invoke(__comp, __rhs, __lhs); @@ -50,7 +50,7 @@ struct __fn { class _Type, class _Proj = identity, indirect_strict_weak_order, _Proj>> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> operator()(_Range&& __r, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const { auto __comp_lhs_rhs_swapped = [&](const auto& __lhs, const auto& __rhs) -> bool { return !std::invoke(__comp, __rhs, __lhs); diff --git a/libcxx/include/__algorithm/remove.h b/libcxx/include/__algorithm/remove.h index 1498852c4361..fd01c23cb670 100644 --- a/libcxx/include/__algorithm/remove.h +++ b/libcxx/include/__algorithm/remove.h @@ -24,7 +24,7 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator remove(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { __first = std::find(__first, __last, __value); if (__first != __last) { diff --git a/libcxx/include/__algorithm/remove_if.h b/libcxx/include/__algorithm/remove_if.h index c77b78023f52..b14f3c0efa7e 100644 --- a/libcxx/include/__algorithm/remove_if.h +++ b/libcxx/include/__algorithm/remove_if.h @@ -23,7 +23,7 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator remove_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { __first = std::find_if<_ForwardIterator, _Predicate&>(__first, __last, __pred); if (__first != __last) { diff --git a/libcxx/include/__algorithm/search.h b/libcxx/include/__algorithm/search.h index 8557c76f80c4..b82ca7809535 100644 --- a/libcxx/include/__algorithm/search.h +++ b/libcxx/include/__algorithm/search.h @@ -160,7 +160,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1> __searc } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, @@ -173,14 +173,14 @@ search(_ForwardIterator1 __first1, } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) { return std::search(__first1, __last1, __first2, __last2, __equal_to()); } #if _LIBCPP_STD_VER >= 17 template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator search(_ForwardIterator __f, _ForwardIterator __l, const _Searcher& __s) { return __s(__f, __l).first; } diff --git a/libcxx/include/__algorithm/search_n.h b/libcxx/include/__algorithm/search_n.h index 12007fa7dea0..771647d3168a 100644 --- a/libcxx/include/__algorithm/search_n.h +++ b/libcxx/include/__algorithm/search_n.h @@ -136,7 +136,7 @@ __search_n_impl(_Iter1 __first, _Sent1 __last, _DiffT __count, const _Type& __va } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator search_n( +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator search_n( _ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value, _BinaryPredicate __pred) { static_assert( __is_callable<_BinaryPredicate, decltype(*__first), const _Tp&>::value, "BinaryPredicate has to be callable"); @@ -145,7 +145,7 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator search_n(_ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value) { return std::search_n(__first, __last, std::__convert_to_integral(__count), __value, __equal_to()); } diff --git a/libcxx/include/__algorithm/unique.h b/libcxx/include/__algorithm/unique.h index 056373d06fe4..d597014596f2 100644 --- a/libcxx/include/__algorithm/unique.h +++ b/libcxx/include/__algorithm/unique.h @@ -29,7 +29,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD // unique template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 std::pair<_Iter, _Iter> +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 std::pair<_Iter, _Iter> __unique(_Iter __first, _Sent __last, _BinaryPredicate&& __pred) { __first = std::__adjacent_find(__first, __last, __pred); if (__first != __last) { @@ -46,13 +46,13 @@ __unique(_Iter __first, _Sent __last, _BinaryPredicate&& __pred) { } template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator unique(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) { return std::__unique<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __pred).first; } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator unique(_ForwardIterator __first, _ForwardIterator __last) { return std::unique(__first, __last, __equal_to()); } diff --git a/libcxx/include/__algorithm/upper_bound.h b/libcxx/include/__algorithm/upper_bound.h index 9c7d8fbcde07..c39dec2e8969 100644 --- a/libcxx/include/__algorithm/upper_bound.h +++ b/libcxx/include/__algorithm/upper_bound.h @@ -48,7 +48,7 @@ __upper_bound(_Iter __first, _Sent __last, const _Tp& __value, _Compare&& __comp } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) { static_assert(is_copy_constructible<_ForwardIterator>::value, "Iterator has to be copy constructible"); return std::__upper_bound<_ClassicAlgPolicy>( @@ -56,7 +56,7 @@ upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __valu } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { return std::upper_bound(std::move(__first), std::move(__last), __value, __less<>()); } diff --git a/libcxx/include/__bit/bit_cast.h b/libcxx/include/__bit/bit_cast.h index 6298810f3733..cd0456738179 100644 --- a/libcxx/include/__bit/bit_cast.h +++ b/libcxx/include/__bit/bit_cast.h @@ -33,7 +33,7 @@ _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI constexpr _ToType __bit_cast(const _From template requires(sizeof(_ToType) == sizeof(_FromType) && is_trivially_copyable_v<_ToType> && is_trivially_copyable_v<_FromType>) -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _ToType bit_cast(const _FromType& __from) noexcept { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _ToType bit_cast(const _FromType& __from) noexcept { return __builtin_bit_cast(_ToType, __from); } diff --git a/libcxx/include/__bit/bit_ceil.h b/libcxx/include/__bit/bit_ceil.h index 77fa739503bc..cfd792dc2e2a 100644 --- a/libcxx/include/__bit/bit_ceil.h +++ b/libcxx/include/__bit/bit_ceil.h @@ -24,7 +24,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 17 template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Tp __bit_ceil(_Tp __t) noexcept { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp __bit_ceil(_Tp __t) noexcept { if (__t < 2) return 1; const unsigned __n = numeric_limits<_Tp>::digits - std::__countl_zero((_Tp)(__t - 1u)); @@ -42,7 +42,7 @@ _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Tp __bit_ceil(_Tp __t) no # if _LIBCPP_STD_VER >= 20 template <__libcpp_unsigned_integer _Tp> -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Tp bit_ceil(_Tp __t) noexcept { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp bit_ceil(_Tp __t) noexcept { return std::__bit_ceil(__t); } diff --git a/libcxx/include/__bit/bit_floor.h b/libcxx/include/__bit/bit_floor.h index cf5cf5803ad6..133e369504e4 100644 --- a/libcxx/include/__bit/bit_floor.h +++ b/libcxx/include/__bit/bit_floor.h @@ -23,7 +23,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 template <__libcpp_unsigned_integer _Tp> -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Tp bit_floor(_Tp __t) noexcept { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp bit_floor(_Tp __t) noexcept { return __t == 0 ? 0 : _Tp{1} << std::__bit_log2(__t); } diff --git a/libcxx/include/__bit/bit_width.h b/libcxx/include/__bit/bit_width.h index a2020a01421e..853e481776f7 100644 --- a/libcxx/include/__bit/bit_width.h +++ b/libcxx/include/__bit/bit_width.h @@ -22,7 +22,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template <__libcpp_unsigned_integer _Tp> -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr int bit_width(_Tp __t) noexcept { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr int bit_width(_Tp __t) noexcept { return __t == 0 ? 0 : std::__bit_log2(__t) + 1; } diff --git a/libcxx/include/__bit/byteswap.h b/libcxx/include/__bit/byteswap.h index 20045d6fd43c..6225ecf2f92d 100644 --- a/libcxx/include/__bit/byteswap.h +++ b/libcxx/include/__bit/byteswap.h @@ -23,7 +23,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 23 template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Tp byteswap(_Tp __val) noexcept { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp byteswap(_Tp __val) noexcept { if constexpr (sizeof(_Tp) == 1) { return __val; } else if constexpr (sizeof(_Tp) == 2) { diff --git a/libcxx/include/__bit/countl.h b/libcxx/include/__bit/countl.h index 13df8d4e66c4..998a0b44c19d 100644 --- a/libcxx/include/__bit/countl.h +++ b/libcxx/include/__bit/countl.h @@ -95,12 +95,12 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 int __countl_zero(_Tp __t) _ #if _LIBCPP_STD_VER >= 20 template <__libcpp_unsigned_integer _Tp> -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr int countl_zero(_Tp __t) noexcept { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr int countl_zero(_Tp __t) noexcept { return std::__countl_zero(__t); } template <__libcpp_unsigned_integer _Tp> -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr int countl_one(_Tp __t) noexcept { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr int countl_one(_Tp __t) noexcept { return __t != numeric_limits<_Tp>::max() ? std::countl_zero(static_cast<_Tp>(~__t)) : numeric_limits<_Tp>::digits; } diff --git a/libcxx/include/__bit/countr.h b/libcxx/include/__bit/countr.h index 724a0bc23801..9e92021fba35 100644 --- a/libcxx/include/__bit/countr.h +++ b/libcxx/include/__bit/countr.h @@ -66,12 +66,12 @@ _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 int __coun #if _LIBCPP_STD_VER >= 20 template <__libcpp_unsigned_integer _Tp> -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr int countr_zero(_Tp __t) noexcept { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr int countr_zero(_Tp __t) noexcept { return std::__countr_zero(__t); } template <__libcpp_unsigned_integer _Tp> -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr int countr_one(_Tp __t) noexcept { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr int countr_one(_Tp __t) noexcept { return __t != numeric_limits<_Tp>::max() ? std::countr_zero(static_cast<_Tp>(~__t)) : numeric_limits<_Tp>::digits; } diff --git a/libcxx/include/__bit/has_single_bit.h b/libcxx/include/__bit/has_single_bit.h index a4e178060a73..52f5853a1bc8 100644 --- a/libcxx/include/__bit/has_single_bit.h +++ b/libcxx/include/__bit/has_single_bit.h @@ -24,7 +24,7 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD template <__libcpp_unsigned_integer _Tp> -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool has_single_bit(_Tp __t) noexcept { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool has_single_bit(_Tp __t) noexcept { return __t != 0 && (((__t & (__t - 1)) == 0)); } diff --git a/libcxx/include/__bit/popcount.h b/libcxx/include/__bit/popcount.h index 37b3a3e1f3f2..5cf0a01d0733 100644 --- a/libcxx/include/__bit/popcount.h +++ b/libcxx/include/__bit/popcount.h @@ -41,7 +41,7 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int __libcpp_popcount(unsigned lo #if _LIBCPP_STD_VER >= 20 template <__libcpp_unsigned_integer _Tp> -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr int popcount(_Tp __t) noexcept { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr int popcount(_Tp __t) noexcept { # if __has_builtin(__builtin_popcountg) return __builtin_popcountg(__t); # else // __has_builtin(__builtin_popcountg) diff --git a/libcxx/include/__chrono/leap_second.h b/libcxx/include/__chrono/leap_second.h index 2bbf06364673..1a0e7f3107de 100644 --- a/libcxx/include/__chrono/leap_second.h +++ b/libcxx/include/__chrono/leap_second.h @@ -43,9 +43,9 @@ public: _LIBCPP_HIDE_FROM_ABI leap_second(const leap_second&) = default; _LIBCPP_HIDE_FROM_ABI leap_second& operator=(const leap_second&) = default; - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr sys_seconds date() const noexcept { return __date_; } + _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI constexpr sys_seconds date() const noexcept { return __date_; } - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr seconds value() const noexcept { return __value_; } + _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI constexpr seconds value() const noexcept { return __value_; } private: sys_seconds __date_; diff --git a/libcxx/include/__chrono/time_zone.h b/libcxx/include/__chrono/time_zone.h index 799602c1cdba..91ddab8903fe 100644 --- a/libcxx/include/__chrono/time_zone.h +++ b/libcxx/include/__chrono/time_zone.h @@ -56,10 +56,10 @@ public: _LIBCPP_HIDE_FROM_ABI time_zone(time_zone&&) = default; _LIBCPP_HIDE_FROM_ABI time_zone& operator=(time_zone&&) = default; - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI string_view name() const noexcept { return __name(); } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI string_view name() const noexcept { return __name(); } template - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI sys_info get_info(const sys_time<_Duration>& __time) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI sys_info get_info(const sys_time<_Duration>& __time) const { return __get_info(chrono::time_point_cast(__time)); } @@ -73,12 +73,12 @@ private: unique_ptr<__impl> __impl_; }; -_LIBCPP_NODISCARD_EXT _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline bool +[[nodiscard]] _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline bool operator==(const time_zone& __x, const time_zone& __y) noexcept { return __x.name() == __y.name(); } -_LIBCPP_NODISCARD_EXT _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline strong_ordering +[[nodiscard]] _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline strong_ordering operator<=>(const time_zone& __x, const time_zone& __y) noexcept { return __x.name() <=> __y.name(); } diff --git a/libcxx/include/__chrono/time_zone_link.h b/libcxx/include/__chrono/time_zone_link.h index f44137829a81..b2d365c5fd08 100644 --- a/libcxx/include/__chrono/time_zone_link.h +++ b/libcxx/include/__chrono/time_zone_link.h @@ -38,15 +38,15 @@ namespace chrono { class time_zone_link { public: - _LIBCPP_NODISCARD_EXT + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI explicit time_zone_link(__private_constructor_tag, string_view __name, string_view __target) : __name_{__name}, __target_{__target} {} _LIBCPP_HIDE_FROM_ABI time_zone_link(time_zone_link&&) = default; _LIBCPP_HIDE_FROM_ABI time_zone_link& operator=(time_zone_link&&) = default; - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI string_view name() const noexcept { return __name_; } - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI string_view target() const noexcept { return __target_; } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI string_view name() const noexcept { return __name_; } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI string_view target() const noexcept { return __target_; } private: string __name_; @@ -56,12 +56,12 @@ private: string __target_; }; -_LIBCPP_NODISCARD_EXT _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline bool +[[nodiscard]] _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline bool operator==(const time_zone_link& __x, const time_zone_link& __y) noexcept { return __x.name() == __y.name(); } -_LIBCPP_NODISCARD_EXT _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline strong_ordering +[[nodiscard]] _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline strong_ordering operator<=>(const time_zone_link& __x, const time_zone_link& __y) noexcept { return __x.name() <=> __y.name(); } diff --git a/libcxx/include/__chrono/tzdb.h b/libcxx/include/__chrono/tzdb.h index 12fe6ccb63f9..f731f8c318be 100644 --- a/libcxx/include/__chrono/tzdb.h +++ b/libcxx/include/__chrono/tzdb.h @@ -57,14 +57,14 @@ struct tzdb { return nullptr; } - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI const time_zone* locate_zone(string_view __name) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI const time_zone* locate_zone(string_view __name) const { if (const time_zone* __result = __locate_zone(__name)) return __result; std::__throw_runtime_error("tzdb: requested time zone not found"); } - _LIBCPP_NODISCARD_EXT _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI const time_zone* current_zone() const { + [[nodiscard]] _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI const time_zone* current_zone() const { return __current_zone(); } diff --git a/libcxx/include/__chrono/tzdb_list.h b/libcxx/include/__chrono/tzdb_list.h index ae27067dbf02..62db7e3d2e0b 100644 --- a/libcxx/include/__chrono/tzdb_list.h +++ b/libcxx/include/__chrono/tzdb_list.h @@ -53,15 +53,15 @@ public: using const_iterator = forward_list::const_iterator; - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI const tzdb& front() const noexcept { return __front(); } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI const tzdb& front() const noexcept { return __front(); } _LIBCPP_HIDE_FROM_ABI const_iterator erase_after(const_iterator __p) { return __erase_after(__p); } - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI const_iterator begin() const noexcept { return __begin(); } - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI const_iterator end() const noexcept { return __end(); } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI const_iterator begin() const noexcept { return __begin(); } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI const_iterator end() const noexcept { return __end(); } - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const noexcept { return __cbegin(); } - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI const_iterator cend() const noexcept { return __cend(); } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const noexcept { return __cbegin(); } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI const_iterator cend() const noexcept { return __cend(); } [[nodiscard]] _LIBCPP_HIDE_FROM_ABI __impl& __implementation() { return *__impl_; } @@ -79,24 +79,23 @@ private: __impl* __impl_; }; -_LIBCPP_NODISCARD_EXT _LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI tzdb_list& get_tzdb_list(); +[[nodiscard]] _LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI tzdb_list& get_tzdb_list(); -_LIBCPP_NODISCARD_EXT _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline const tzdb& get_tzdb() { +[[nodiscard]] _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline const tzdb& get_tzdb() { return get_tzdb_list().front(); } -_LIBCPP_NODISCARD_EXT _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline const time_zone* -locate_zone(string_view __name) { +[[nodiscard]] _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline const time_zone* locate_zone(string_view __name) { return get_tzdb().locate_zone(__name); } -_LIBCPP_NODISCARD_EXT _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline const time_zone* current_zone() { +[[nodiscard]] _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline const time_zone* current_zone() { return get_tzdb().current_zone(); } _LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI const tzdb& reload_tzdb(); -_LIBCPP_NODISCARD_EXT _LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI string remote_version(); +[[nodiscard]] _LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI string remote_version(); } // namespace chrono diff --git a/libcxx/include/__config b/libcxx/include/__config index 4f5c1476626d..97cdd020c55d 100644 --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -1375,7 +1375,7 @@ typedef __char32_t char32_t; # define _LIBCPP_USING_IF_EXISTS # endif -# if __has_cpp_attribute(nodiscard) +# if __has_cpp_attribute(__nodiscard__) # define _LIBCPP_NODISCARD [[__nodiscard__]] # else // We can't use GCC's [[gnu::warn_unused_result]] and @@ -1384,20 +1384,6 @@ typedef __char32_t char32_t; # define _LIBCPP_NODISCARD # endif -// _LIBCPP_NODISCARD_EXT may be used to apply [[nodiscard]] to entities not -// specified as such as an extension. -# if !defined(_LIBCPP_DISABLE_NODISCARD_EXT) -# define _LIBCPP_NODISCARD_EXT _LIBCPP_NODISCARD -# else -# define _LIBCPP_NODISCARD_EXT -# endif - -# if _LIBCPP_STD_VER >= 20 || !defined(_LIBCPP_DISABLE_NODISCARD_EXT) -# define _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_NODISCARD -# else -# define _LIBCPP_NODISCARD_AFTER_CXX17 -# endif - # if __has_attribute(__no_destroy__) # define _LIBCPP_NO_DESTROY __attribute__((__no_destroy__)) # else diff --git a/libcxx/include/__filesystem/path.h b/libcxx/include/__filesystem/path.h index 9ffc90ada5e7..89d319b4b19b 100644 --- a/libcxx/include/__filesystem/path.h +++ b/libcxx/include/__filesystem/path.h @@ -812,7 +812,7 @@ public: _LIBCPP_HIDE_FROM_ABI path extension() const { return string_type(__extension()); } // query - _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI bool empty() const noexcept { return __pn_.empty(); } + _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI bool empty() const noexcept { return __pn_.empty(); } _LIBCPP_HIDE_FROM_ABI bool has_root_name() const { return !__root_name().empty(); } _LIBCPP_HIDE_FROM_ABI bool has_root_directory() const { return !__root_directory().empty(); } diff --git a/libcxx/include/__format/format_functions.h b/libcxx/include/__format/format_functions.h index c7810140105a..d14b49aff149 100644 --- a/libcxx/include/__format/format_functions.h +++ b/libcxx/include/__format/format_functions.h @@ -66,14 +66,13 @@ using wformat_args = basic_format_args; # endif template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI __format_arg_store<_Context, _Args...> make_format_args(_Args&... __args) { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI __format_arg_store<_Context, _Args...> make_format_args(_Args&... __args) { return std::__format_arg_store<_Context, _Args...>(__args...); } # ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI __format_arg_store -make_wformat_args(_Args&... __args) { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI __format_arg_store make_wformat_args(_Args&... __args) { return std::__format_arg_store(__args...); } # endif @@ -452,8 +451,7 @@ format_to(_OutIt __out_it, wformat_string<_Args...> __fmt, _Args&&... __args) { // TODO FMT This needs to be a template or std::to_chars(floating-point) availability markup // fires too eagerly, see http://llvm.org/PR61563. template -_LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI string -vformat(string_view __fmt, format_args __args) { +[[nodiscard]] _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI string vformat(string_view __fmt, format_args __args) { string __res; std::vformat_to(std::back_inserter(__res), __fmt, __args); return __res; @@ -463,7 +461,7 @@ vformat(string_view __fmt, format_args __args) { // TODO FMT This needs to be a template or std::to_chars(floating-point) availability markup // fires too eagerly, see http://llvm.org/PR61563. template -_LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI wstring +[[nodiscard]] _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI wstring vformat(wstring_view __fmt, wformat_args __args) { wstring __res; std::vformat_to(std::back_inserter(__res), __fmt, __args); @@ -472,14 +470,14 @@ vformat(wstring_view __fmt, wformat_args __args) { # endif template -_LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI string +[[nodiscard]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI string format(format_string<_Args...> __fmt, _Args&&... __args) { return std::vformat(__fmt.get(), std::make_format_args(__args...)); } # ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS template -_LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI wstring +[[nodiscard]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI wstring format(wformat_string<_Args...> __fmt, _Args&&... __args) { return std::vformat(__fmt.get(), std::make_wformat_args(__args...)); } @@ -520,14 +518,14 @@ _LIBCPP_HIDE_FROM_ABI size_t __vformatted_size(basic_string_view<_CharT> __fmt, } template -_LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t +[[nodiscard]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t formatted_size(format_string<_Args...> __fmt, _Args&&... __args) { return std::__vformatted_size(__fmt.get(), basic_format_args{std::make_format_args(__args...)}); } # ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS template -_LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t +[[nodiscard]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t formatted_size(wformat_string<_Args...> __fmt, _Args&&... __args) { return std::__vformatted_size(__fmt.get(), basic_format_args{std::make_wformat_args(__args...)}); } @@ -585,7 +583,7 @@ format_to(_OutIt __out_it, locale __loc, wformat_string<_Args...> __fmt, _Args&& // TODO FMT This needs to be a template or std::to_chars(floating-point) availability markup // fires too eagerly, see http://llvm.org/PR61563. template -_LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI string +[[nodiscard]] _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI string vformat(locale __loc, string_view __fmt, format_args __args) { string __res; std::vformat_to(std::back_inserter(__res), std::move(__loc), __fmt, __args); @@ -596,7 +594,7 @@ vformat(locale __loc, string_view __fmt, format_args __args) { // TODO FMT This needs to be a template or std::to_chars(floating-point) availability markup // fires too eagerly, see http://llvm.org/PR61563. template -_LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI wstring +[[nodiscard]] _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI wstring vformat(locale __loc, wstring_view __fmt, wformat_args __args) { wstring __res; std::vformat_to(std::back_inserter(__res), std::move(__loc), __fmt, __args); @@ -605,14 +603,14 @@ vformat(locale __loc, wstring_view __fmt, wformat_args __args) { # endif template -_LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI string +[[nodiscard]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI string format(locale __loc, format_string<_Args...> __fmt, _Args&&... __args) { return std::vformat(std::move(__loc), __fmt.get(), std::make_format_args(__args...)); } # ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS template -_LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI wstring +[[nodiscard]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI wstring format(locale __loc, wformat_string<_Args...> __fmt, _Args&&... __args) { return std::vformat(std::move(__loc), __fmt.get(), std::make_wformat_args(__args...)); } @@ -658,14 +656,14 @@ _LIBCPP_HIDE_FROM_ABI size_t __vformatted_size(locale __loc, basic_string_view<_ } template -_LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t +[[nodiscard]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t formatted_size(locale __loc, format_string<_Args...> __fmt, _Args&&... __args) { return std::__vformatted_size(std::move(__loc), __fmt.get(), basic_format_args{std::make_format_args(__args...)}); } # ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS template -_LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t +[[nodiscard]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t formatted_size(locale __loc, wformat_string<_Args...> __fmt, _Args&&... __args) { return std::__vformatted_size(std::move(__loc), __fmt.get(), basic_format_args{std::make_wformat_args(__args...)}); } diff --git a/libcxx/include/__functional/identity.h b/libcxx/include/__functional/identity.h index b7be367bd5ee..8468de3dae26 100644 --- a/libcxx/include/__functional/identity.h +++ b/libcxx/include/__functional/identity.h @@ -44,7 +44,7 @@ struct __is_identity > : true_type {}; struct identity { template - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& operator()(_Tp&& __t) const noexcept { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& operator()(_Tp&& __t) const noexcept { return std::forward<_Tp>(__t); } diff --git a/libcxx/include/__iterator/empty.h b/libcxx/include/__iterator/empty.h index 3ca0aff6be46..773f2776955b 100644 --- a/libcxx/include/__iterator/empty.h +++ b/libcxx/include/__iterator/empty.h @@ -23,18 +23,18 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 17 template -_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI constexpr auto empty(const _Cont& __c) - _NOEXCEPT_(noexcept(__c.empty())) -> decltype(__c.empty()) { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto +empty(const _Cont& __c) noexcept(noexcept(__c.empty())) -> decltype(__c.empty()) { return __c.empty(); } template -_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI constexpr bool empty(const _Tp (&)[_Sz]) noexcept { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty(const _Tp (&)[_Sz]) noexcept { return false; } template -_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI constexpr bool empty(initializer_list<_Ep> __il) noexcept { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty(initializer_list<_Ep> __il) noexcept { return __il.size() == 0; } diff --git a/libcxx/include/__math/abs.h b/libcxx/include/__math/abs.h index 6004690f4c4f..ab82a2800f53 100644 --- a/libcxx/include/__math/abs.h +++ b/libcxx/include/__math/abs.h @@ -23,19 +23,19 @@ namespace __math { // fabs -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float fabs(float __x) _NOEXCEPT { return __builtin_fabsf(__x); } +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI float fabs(float __x) _NOEXCEPT { return __builtin_fabsf(__x); } template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI double fabs(double __x) _NOEXCEPT { +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI double fabs(double __x) _NOEXCEPT { return __builtin_fabs(__x); } -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double fabs(long double __x) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI long double fabs(long double __x) _NOEXCEPT { return __builtin_fabsl(__x); } template ::value, int> = 0> -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI double fabs(_A1 __x) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI double fabs(_A1 __x) _NOEXCEPT { return __builtin_fabs((double)__x); } diff --git a/libcxx/include/__math/copysign.h b/libcxx/include/__math/copysign.h index 2219297e8b8c..b38690bb581a 100644 --- a/libcxx/include/__math/copysign.h +++ b/libcxx/include/__math/copysign.h @@ -25,17 +25,16 @@ namespace __math { // copysign -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float copysign(float __x, float __y) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI float copysign(float __x, float __y) _NOEXCEPT { return ::__builtin_copysignf(__x, __y); } -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double copysign(long double __x, long double __y) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI long double copysign(long double __x, long double __y) _NOEXCEPT { return ::__builtin_copysignl(__x, __y); } template ::value && is_arithmetic<_A2>::value, int> = 0> -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI typename __promote<_A1, _A2>::type -copysign(_A1 __x, _A2 __y) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI typename __promote<_A1, _A2>::type copysign(_A1 __x, _A2 __y) _NOEXCEPT { return ::__builtin_copysign(__x, __y); } diff --git a/libcxx/include/__math/min_max.h b/libcxx/include/__math/min_max.h index 381b2af4a56c..c2c4f6b64560 100644 --- a/libcxx/include/__math/min_max.h +++ b/libcxx/include/__math/min_max.h @@ -25,21 +25,21 @@ namespace __math { // fmax -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float fmax(float __x, float __y) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI float fmax(float __x, float __y) _NOEXCEPT { return __builtin_fmaxf(__x, __y); } template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI double fmax(double __x, double __y) _NOEXCEPT { +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI double fmax(double __x, double __y) _NOEXCEPT { return __builtin_fmax(__x, __y); } -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double fmax(long double __x, long double __y) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI long double fmax(long double __x, long double __y) _NOEXCEPT { return __builtin_fmaxl(__x, __y); } template ::value && is_arithmetic<_A2>::value, int> = 0> -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI typename __promote<_A1, _A2>::type fmax(_A1 __x, _A2 __y) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI typename __promote<_A1, _A2>::type fmax(_A1 __x, _A2 __y) _NOEXCEPT { using __result_type = typename __promote<_A1, _A2>::type; static_assert((!(_IsSame<_A1, __result_type>::value && _IsSame<_A2, __result_type>::value)), ""); return __math::fmax((__result_type)__x, (__result_type)__y); @@ -47,21 +47,21 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI typename __promote<_A1, _A2>: // fmin -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float fmin(float __x, float __y) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI float fmin(float __x, float __y) _NOEXCEPT { return __builtin_fminf(__x, __y); } template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI double fmin(double __x, double __y) _NOEXCEPT { +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI double fmin(double __x, double __y) _NOEXCEPT { return __builtin_fmin(__x, __y); } -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double fmin(long double __x, long double __y) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI long double fmin(long double __x, long double __y) _NOEXCEPT { return __builtin_fminl(__x, __y); } template ::value && is_arithmetic<_A2>::value, int> = 0> -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI typename __promote<_A1, _A2>::type fmin(_A1 __x, _A2 __y) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI typename __promote<_A1, _A2>::type fmin(_A1 __x, _A2 __y) _NOEXCEPT { using __result_type = typename __promote<_A1, _A2>::type; static_assert((!(_IsSame<_A1, __result_type>::value && _IsSame<_A2, __result_type>::value)), ""); return __math::fmin((__result_type)__x, (__result_type)__y); diff --git a/libcxx/include/__math/roots.h b/libcxx/include/__math/roots.h index faee688bc95b..359fd747cfbe 100644 --- a/libcxx/include/__math/roots.h +++ b/libcxx/include/__math/roots.h @@ -39,19 +39,19 @@ inline _LIBCPP_HIDE_FROM_ABI double sqrt(_A1 __x) _NOEXCEPT { // cbrt -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float cbrt(float __x) _NOEXCEPT { return __builtin_cbrtf(__x); } +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI float cbrt(float __x) _NOEXCEPT { return __builtin_cbrtf(__x); } template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI double cbrt(double __x) _NOEXCEPT { +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI double cbrt(double __x) _NOEXCEPT { return __builtin_cbrt(__x); } -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double cbrt(long double __x) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI long double cbrt(long double __x) _NOEXCEPT { return __builtin_cbrtl(__x); } template ::value, int> = 0> -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI double cbrt(_A1 __x) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI double cbrt(_A1 __x) _NOEXCEPT { return __builtin_cbrt((double)__x); } diff --git a/libcxx/include/__math/rounding_functions.h b/libcxx/include/__math/rounding_functions.h index 29e42fd80b00..33e6cbc37d60 100644 --- a/libcxx/include/__math/rounding_functions.h +++ b/libcxx/include/__math/rounding_functions.h @@ -26,37 +26,37 @@ namespace __math { // ceil -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float ceil(float __x) _NOEXCEPT { return __builtin_ceilf(__x); } +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI float ceil(float __x) _NOEXCEPT { return __builtin_ceilf(__x); } template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI double ceil(double __x) _NOEXCEPT { +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI double ceil(double __x) _NOEXCEPT { return __builtin_ceil(__x); } -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double ceil(long double __x) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI long double ceil(long double __x) _NOEXCEPT { return __builtin_ceill(__x); } template ::value, int> = 0> -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI double ceil(_A1 __x) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI double ceil(_A1 __x) _NOEXCEPT { return __builtin_ceil((double)__x); } // floor -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float floor(float __x) _NOEXCEPT { return __builtin_floorf(__x); } +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI float floor(float __x) _NOEXCEPT { return __builtin_floorf(__x); } template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI double floor(double __x) _NOEXCEPT { +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI double floor(double __x) _NOEXCEPT { return __builtin_floor(__x); } -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double floor(long double __x) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI long double floor(long double __x) _NOEXCEPT { return __builtin_floorl(__x); } template ::value, int> = 0> -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI double floor(_A1 __x) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI double floor(_A1 __x) _NOEXCEPT { return __builtin_floor((double)__x); } @@ -126,21 +126,21 @@ inline _LIBCPP_HIDE_FROM_ABI long lround(_A1 __x) _NOEXCEPT { // nearbyint -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float nearbyint(float __x) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI float nearbyint(float __x) _NOEXCEPT { return __builtin_nearbyintf(__x); } template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI double nearbyint(double __x) _NOEXCEPT { +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI double nearbyint(double __x) _NOEXCEPT { return __builtin_nearbyint(__x); } -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double nearbyint(long double __x) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI long double nearbyint(long double __x) _NOEXCEPT { return __builtin_nearbyintl(__x); } template ::value, int> = 0> -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI double nearbyint(_A1 __x) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI double nearbyint(_A1 __x) _NOEXCEPT { return __builtin_nearbyint((double)__x); } @@ -186,55 +186,55 @@ inline _LIBCPP_HIDE_FROM_ABI double nexttoward(_A1 __x, long double __y) _NOEXCE // rint -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float rint(float __x) _NOEXCEPT { return __builtin_rintf(__x); } +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI float rint(float __x) _NOEXCEPT { return __builtin_rintf(__x); } template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI double rint(double __x) _NOEXCEPT { +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI double rint(double __x) _NOEXCEPT { return __builtin_rint(__x); } -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double rint(long double __x) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI long double rint(long double __x) _NOEXCEPT { return __builtin_rintl(__x); } template ::value, int> = 0> -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI double rint(_A1 __x) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI double rint(_A1 __x) _NOEXCEPT { return __builtin_rint((double)__x); } // round -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float round(float __x) _NOEXCEPT { return __builtin_round(__x); } +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI float round(float __x) _NOEXCEPT { return __builtin_round(__x); } template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI double round(double __x) _NOEXCEPT { +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI double round(double __x) _NOEXCEPT { return __builtin_round(__x); } -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double round(long double __x) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI long double round(long double __x) _NOEXCEPT { return __builtin_roundl(__x); } template ::value, int> = 0> -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI double round(_A1 __x) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI double round(_A1 __x) _NOEXCEPT { return __builtin_round((double)__x); } // trunc -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float trunc(float __x) _NOEXCEPT { return __builtin_trunc(__x); } +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI float trunc(float __x) _NOEXCEPT { return __builtin_trunc(__x); } template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI double trunc(double __x) _NOEXCEPT { +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI double trunc(double __x) _NOEXCEPT { return __builtin_trunc(__x); } -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double trunc(long double __x) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI long double trunc(long double __x) _NOEXCEPT { return __builtin_truncl(__x); } template ::value, int> = 0> -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI double trunc(_A1 __x) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI double trunc(_A1 __x) _NOEXCEPT { return __builtin_trunc((double)__x); } diff --git a/libcxx/include/__math/traits.h b/libcxx/include/__math/traits.h index da585af8837f..a44826679755 100644 --- a/libcxx/include/__math/traits.h +++ b/libcxx/include/__math/traits.h @@ -29,55 +29,55 @@ namespace __math { // signbit template ::value, int> = 0> -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool signbit(_A1 __x) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool signbit(_A1 __x) _NOEXCEPT { return __builtin_signbit(__x); } template ::value && is_signed<_A1>::value, int> = 0> -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool signbit(_A1 __x) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool signbit(_A1 __x) _NOEXCEPT { return __x < 0; } template ::value && !is_signed<_A1>::value, int> = 0> -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool signbit(_A1) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool signbit(_A1) _NOEXCEPT { return false; } // isfinite template ::value && numeric_limits<_A1>::has_infinity, int> = 0> -_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isfinite(_A1 __x) _NOEXCEPT { +_LIBCPP_NODISCARD _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isfinite(_A1 __x) _NOEXCEPT { return __builtin_isfinite((typename __promote<_A1>::type)__x); } template ::value && !numeric_limits<_A1>::has_infinity, int> = 0> -_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isfinite(_A1) _NOEXCEPT { +_LIBCPP_NODISCARD _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isfinite(_A1) _NOEXCEPT { return true; } // isinf template ::value && numeric_limits<_A1>::has_infinity, int> = 0> -_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isinf(_A1 __x) _NOEXCEPT { +_LIBCPP_NODISCARD _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isinf(_A1 __x) _NOEXCEPT { return __builtin_isinf((typename __promote<_A1>::type)__x); } template ::value && !numeric_limits<_A1>::has_infinity, int> = 0> -_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isinf(_A1) _NOEXCEPT { +_LIBCPP_NODISCARD _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isinf(_A1) _NOEXCEPT { return false; } #ifdef _LIBCPP_PREFERRED_OVERLOAD -_LIBCPP_NODISCARD_EXT inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isinf(float __x) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isinf(float __x) _NOEXCEPT { return __builtin_isinf(__x); } -_LIBCPP_NODISCARD_EXT inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI _LIBCPP_PREFERRED_OVERLOAD bool +_LIBCPP_NODISCARD inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI _LIBCPP_PREFERRED_OVERLOAD bool isinf(double __x) _NOEXCEPT { return __builtin_isinf(__x); } -_LIBCPP_NODISCARD_EXT inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isinf(long double __x) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isinf(long double __x) _NOEXCEPT { return __builtin_isinf(__x); } #endif @@ -85,26 +85,26 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI // isnan template ::value, int> = 0> -_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan(_A1 __x) _NOEXCEPT { +_LIBCPP_NODISCARD _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan(_A1 __x) _NOEXCEPT { return __builtin_isnan(__x); } template ::value, int> = 0> -_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan(_A1) _NOEXCEPT { +_LIBCPP_NODISCARD _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan(_A1) _NOEXCEPT { return false; } #ifdef _LIBCPP_PREFERRED_OVERLOAD -_LIBCPP_NODISCARD_EXT inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan(float __x) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan(float __x) _NOEXCEPT { return __builtin_isnan(__x); } -_LIBCPP_NODISCARD_EXT inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI _LIBCPP_PREFERRED_OVERLOAD bool +_LIBCPP_NODISCARD inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI _LIBCPP_PREFERRED_OVERLOAD bool isnan(double __x) _NOEXCEPT { return __builtin_isnan(__x); } -_LIBCPP_NODISCARD_EXT inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan(long double __x) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnan(long double __x) _NOEXCEPT { return __builtin_isnan(__x); } #endif @@ -112,19 +112,19 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI // isnormal template ::value, int> = 0> -_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnormal(_A1 __x) _NOEXCEPT { +_LIBCPP_NODISCARD _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnormal(_A1 __x) _NOEXCEPT { return __builtin_isnormal(__x); } template ::value, int> = 0> -_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnormal(_A1 __x) _NOEXCEPT { +_LIBCPP_NODISCARD _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool isnormal(_A1 __x) _NOEXCEPT { return __x != 0; } // isgreater template ::value && is_arithmetic<_A2>::value, int> = 0> -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool isgreater(_A1 __x, _A2 __y) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool isgreater(_A1 __x, _A2 __y) _NOEXCEPT { using type = typename __promote<_A1, _A2>::type; return __builtin_isgreater((type)__x, (type)__y); } @@ -132,7 +132,7 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool isgreater(_A1 __x, _A2 _ // isgreaterequal template ::value && is_arithmetic<_A2>::value, int> = 0> -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool isgreaterequal(_A1 __x, _A2 __y) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool isgreaterequal(_A1 __x, _A2 __y) _NOEXCEPT { using type = typename __promote<_A1, _A2>::type; return __builtin_isgreaterequal((type)__x, (type)__y); } @@ -140,7 +140,7 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool isgreaterequal(_A1 __x, // isless template ::value && is_arithmetic<_A2>::value, int> = 0> -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool isless(_A1 __x, _A2 __y) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool isless(_A1 __x, _A2 __y) _NOEXCEPT { using type = typename __promote<_A1, _A2>::type; return __builtin_isless((type)__x, (type)__y); } @@ -148,7 +148,7 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool isless(_A1 __x, _A2 __y) // islessequal template ::value && is_arithmetic<_A2>::value, int> = 0> -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool islessequal(_A1 __x, _A2 __y) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool islessequal(_A1 __x, _A2 __y) _NOEXCEPT { using type = typename __promote<_A1, _A2>::type; return __builtin_islessequal((type)__x, (type)__y); } @@ -156,7 +156,7 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool islessequal(_A1 __x, _A2 // islessgreater template ::value && is_arithmetic<_A2>::value, int> = 0> -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool islessgreater(_A1 __x, _A2 __y) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool islessgreater(_A1 __x, _A2 __y) _NOEXCEPT { using type = typename __promote<_A1, _A2>::type; return __builtin_islessgreater((type)__x, (type)__y); } @@ -164,7 +164,7 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool islessgreater(_A1 __x, _ // isunordered template ::value && is_arithmetic<_A2>::value, int> = 0> -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool isunordered(_A1 __x, _A2 __y) _NOEXCEPT { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool isunordered(_A1 __x, _A2 __y) _NOEXCEPT { using type = typename __promote<_A1, _A2>::type; return __builtin_isunordered((type)__x, (type)__y); } diff --git a/libcxx/include/__memory/allocator.h b/libcxx/include/__memory/allocator.h index 26e5d4978b15..215d3832f9ef 100644 --- a/libcxx/include/__memory/allocator.h +++ b/libcxx/include/__memory/allocator.h @@ -110,7 +110,7 @@ public: template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 allocator(const allocator<_Up>&) _NOEXCEPT {} - _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp* allocate(size_t __n) { + _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp* allocate(size_t __n) { if (__n > allocator_traits::max_size(*this)) __throw_bad_array_new_length(); if (__libcpp_is_constant_evaluated()) { @@ -153,8 +153,7 @@ public: return std::addressof(__x); } - _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX17 _Tp* - allocate(size_t __n, const void*) { + _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX17 _Tp* allocate(size_t __n, const void*) { return allocate(__n); } @@ -190,7 +189,7 @@ public: template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 allocator(const allocator<_Up>&) _NOEXCEPT {} - _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const _Tp* allocate(size_t __n) { + _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const _Tp* allocate(size_t __n) { if (__n > allocator_traits::max_size(*this)) __throw_bad_array_new_length(); if (__libcpp_is_constant_evaluated()) { @@ -230,8 +229,7 @@ public: return std::addressof(__x); } - _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX17 const _Tp* - allocate(size_t __n, const void*) { + _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX17 const _Tp* allocate(size_t __n, const void*) { return allocate(__n); } diff --git a/libcxx/include/__memory/allocator_traits.h b/libcxx/include/__memory/allocator_traits.h index 7b3deb0f58e9..47fe132d15cb 100644 --- a/libcxx/include/__memory/allocator_traits.h +++ b/libcxx/include/__memory/allocator_traits.h @@ -275,13 +275,13 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits { }; #endif // _LIBCPP_CXX03_LANG - _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static pointer + _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static pointer allocate(allocator_type& __a, size_type __n) { return __a.allocate(__n); } template ::value, int> = 0> - _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static pointer + _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static pointer allocate(allocator_type& __a, size_type __n, const_void_pointer __hint) { _LIBCPP_SUPPRESS_DEPRECATED_PUSH return __a.allocate(__n, __hint); @@ -290,7 +290,7 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits { template ::value, int> = 0> - _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static pointer + _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static pointer allocate(allocator_type& __a, size_type __n, const_void_pointer) { return __a.allocate(__n); } diff --git a/libcxx/include/__memory/temporary_buffer.h b/libcxx/include/__memory/temporary_buffer.h index e3797caff8c9..88799ca95c1f 100644 --- a/libcxx/include/__memory/temporary_buffer.h +++ b/libcxx/include/__memory/temporary_buffer.h @@ -22,7 +22,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI _LIBCPP_DEPRECATED_IN_CXX17 pair<_Tp*, ptrdiff_t> +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI _LIBCPP_DEPRECATED_IN_CXX17 pair<_Tp*, ptrdiff_t> get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT { pair<_Tp*, ptrdiff_t> __r(0, 0); const ptrdiff_t __m = diff --git a/libcxx/include/__memory_resource/memory_resource.h b/libcxx/include/__memory_resource/memory_resource.h index 418f36dc9b39..e605838bf5ea 100644 --- a/libcxx/include/__memory_resource/memory_resource.h +++ b/libcxx/include/__memory_resource/memory_resource.h @@ -32,9 +32,8 @@ class _LIBCPP_AVAILABILITY_PMR _LIBCPP_EXPORTED_FROM_ABI memory_resource { public: virtual ~memory_resource(); - _LIBCPP_NODISCARD_AFTER_CXX17 - [[using __gnu__: __returns_nonnull__, __alloc_size__(2), __alloc_align__(3)]] _LIBCPP_HIDE_FROM_ABI void* - allocate(size_t __bytes, size_t __align = __max_align) { + [[nodiscard]] [[using __gnu__: __returns_nonnull__, __alloc_size__(2), __alloc_align__(3)]] + _LIBCPP_HIDE_FROM_ABI void* allocate(size_t __bytes, size_t __align = __max_align) { return do_allocate(__bytes, __align); } diff --git a/libcxx/include/__memory_resource/polymorphic_allocator.h b/libcxx/include/__memory_resource/polymorphic_allocator.h index 823c1503c22b..8fda20112438 100644 --- a/libcxx/include/__memory_resource/polymorphic_allocator.h +++ b/libcxx/include/__memory_resource/polymorphic_allocator.h @@ -61,7 +61,7 @@ public: // [mem.poly.allocator.mem] - _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI _ValueType* allocate(size_t __n) { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _ValueType* allocate(size_t __n) { if (__n > __max_size()) { __throw_bad_array_new_length(); } diff --git a/libcxx/include/__mutex/lock_guard.h b/libcxx/include/__mutex/lock_guard.h index c075512fb97a..739d1683b317 100644 --- a/libcxx/include/__mutex/lock_guard.h +++ b/libcxx/include/__mutex/lock_guard.h @@ -29,13 +29,13 @@ private: mutex_type& __m_; public: - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI explicit lock_guard(mutex_type& __m) - _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_capability(__m)) + _LIBCPP_NODISCARD + _LIBCPP_HIDE_FROM_ABI explicit lock_guard(mutex_type& __m) _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_capability(__m)) : __m_(__m) { __m_.lock(); } - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI lock_guard(mutex_type& __m, adopt_lock_t) + _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI lock_guard(mutex_type& __m, adopt_lock_t) _LIBCPP_THREAD_SAFETY_ANNOTATION(requires_capability(__m)) : __m_(__m) {} _LIBCPP_HIDE_FROM_ABI ~lock_guard() _LIBCPP_THREAD_SAFETY_ANNOTATION(release_capability()) { __m_.unlock(); } diff --git a/libcxx/include/__node_handle b/libcxx/include/__node_handle index 24d2624c3739..d0b35bfd1934 100644 --- a/libcxx/include/__node_handle +++ b/libcxx/include/__node_handle @@ -147,7 +147,7 @@ public: _LIBCPP_HIDE_FROM_ABI explicit operator bool() const { return __ptr_ != nullptr; } - _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI bool empty() const { return __ptr_ == nullptr; } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool empty() const { return __ptr_ == nullptr; } _LIBCPP_HIDE_FROM_ABI void swap(__basic_node_handle& __other) noexcept( __alloc_traits::propagate_on_container_swap::value || __alloc_traits::is_always_equal::value) { diff --git a/libcxx/include/__ranges/as_rvalue_view.h b/libcxx/include/__ranges/as_rvalue_view.h index 2fc272e798d6..5849a6c36839 100644 --- a/libcxx/include/__ranges/as_rvalue_view.h +++ b/libcxx/include/__ranges/as_rvalue_view.h @@ -111,7 +111,7 @@ namespace views { namespace __as_rvalue { struct __fn : __range_adaptor_closure<__fn> { template - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI static constexpr auto + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Range&& __range) noexcept(noexcept(as_rvalue_view(std::forward<_Range>(__range)))) -> decltype(/*--------------------------*/ as_rvalue_view(std::forward<_Range>(__range))) { return /*---------------------------------*/ as_rvalue_view(std::forward<_Range>(__range)); @@ -119,7 +119,7 @@ struct __fn : __range_adaptor_closure<__fn> { template requires same_as, range_reference_t<_Range>> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI static constexpr auto + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Range&& __range) noexcept(noexcept(views::all(std::forward<_Range>(__range)))) -> decltype(/*--------------------------*/ views::all(std::forward<_Range>(__range))) { return /*---------------------------------*/ views::all(std::forward<_Range>(__range)); diff --git a/libcxx/include/__ranges/chunk_by_view.h b/libcxx/include/__ranges/chunk_by_view.h index b04a23de99fb..00014d9f10ae 100644 --- a/libcxx/include/__ranges/chunk_by_view.h +++ b/libcxx/include/__ranges/chunk_by_view.h @@ -205,7 +205,7 @@ namespace views { namespace __chunk_by { struct __fn { template - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Pred&& __pred) const + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Pred&& __pred) const noexcept(noexcept(/**/ chunk_by_view(std::forward<_Range>(__range), std::forward<_Pred>(__pred)))) -> decltype(/*--*/ chunk_by_view(std::forward<_Range>(__range), std::forward<_Pred>(__pred))) { return /*-------------*/ chunk_by_view(std::forward<_Range>(__range), std::forward<_Pred>(__pred)); @@ -213,7 +213,7 @@ struct __fn { template requires constructible_from, _Pred> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Pred&& __pred) const + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Pred&& __pred) const noexcept(is_nothrow_constructible_v, _Pred>) { return __range_adaptor_closure_t(std::__bind_back(*this, std::forward<_Pred>(__pred))); } diff --git a/libcxx/include/__ranges/drop_view.h b/libcxx/include/__ranges/drop_view.h index 83bb598b0a0c..fbfbca4db621 100644 --- a/libcxx/include/__ranges/drop_view.h +++ b/libcxx/include/__ranges/drop_view.h @@ -266,7 +266,7 @@ struct __fn { class _RawRange = remove_cvref_t<_Range>, class _Dist = range_difference_t<_Range>> requires (__is_repeat_specialization<_RawRange> && sized_range<_RawRange>) - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Np&& __n) const + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Np&& __n) const noexcept(noexcept(views::repeat(*__range.__value_, ranges::distance(__range) - std::min<_Dist>(ranges::distance(__range), std::forward<_Np>(__n))))) -> decltype( views::repeat(*__range.__value_, ranges::distance(__range) - std::min<_Dist>(ranges::distance(__range), std::forward<_Np>(__n)))) { return views::repeat(*__range.__value_, ranges::distance(__range) - std::min<_Dist>(ranges::distance(__range), std::forward<_Np>(__n))); } @@ -277,7 +277,7 @@ struct __fn { class _RawRange = remove_cvref_t<_Range>, class _Dist = range_difference_t<_Range>> requires (__is_repeat_specialization<_RawRange> && !sized_range<_RawRange>) - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Np&&) const noexcept(noexcept(_LIBCPP_AUTO_CAST(std::forward<_Range>(__range)))) -> decltype( _LIBCPP_AUTO_CAST(std::forward<_Range>(__range))) diff --git a/libcxx/include/__ranges/repeat_view.h b/libcxx/include/__ranges/repeat_view.h index 5caea757a393..0941770f0eef 100644 --- a/libcxx/include/__ranges/repeat_view.h +++ b/libcxx/include/__ranges/repeat_view.h @@ -229,13 +229,13 @@ namespace views { namespace __repeat { struct __fn { template - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Tp&& __value) + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Tp&& __value) noexcept(noexcept(ranges::repeat_view(std::forward<_Tp>(__value)))) -> decltype( ranges::repeat_view(std::forward<_Tp>(__value))) { return ranges::repeat_view(std::forward<_Tp>(__value)); } template - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Tp&& __value, _Bound&& __bound_sentinel) + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Tp&& __value, _Bound&& __bound_sentinel) noexcept(noexcept(ranges::repeat_view(std::forward<_Tp>(__value), std::forward<_Bound>(__bound_sentinel)))) -> decltype( ranges::repeat_view(std::forward<_Tp>(__value), std::forward<_Bound>(__bound_sentinel))) { return ranges::repeat_view(std::forward<_Tp>(__value), std::forward<_Bound>(__bound_sentinel)); } diff --git a/libcxx/include/__ranges/split_view.h b/libcxx/include/__ranges/split_view.h index 98f17be04f62..ce3606aedfef 100644 --- a/libcxx/include/__ranges/split_view.h +++ b/libcxx/include/__ranges/split_view.h @@ -200,7 +200,7 @@ namespace __split_view { struct __fn { // clang-format off template - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Pattern&& __pattern) const noexcept(noexcept(split_view(std::forward<_Range>(__range), std::forward<_Pattern>(__pattern)))) -> decltype( split_view(std::forward<_Range>(__range), std::forward<_Pattern>(__pattern))) @@ -209,7 +209,7 @@ struct __fn { template requires constructible_from, _Pattern> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Pattern&& __pattern) const + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Pattern&& __pattern) const noexcept(is_nothrow_constructible_v, _Pattern>) { return __range_adaptor_closure_t(std::__bind_back(*this, std::forward<_Pattern>(__pattern))); } diff --git a/libcxx/include/__ranges/take_view.h b/libcxx/include/__ranges/take_view.h index 83ed5ca0ebd3..27ca8155a69b 100644 --- a/libcxx/include/__ranges/take_view.h +++ b/libcxx/include/__ranges/take_view.h @@ -308,7 +308,7 @@ struct __fn { class _RawRange = remove_cvref_t<_Range>, class _Dist = range_difference_t<_Range>> requires(__is_repeat_specialization<_RawRange> && sized_range<_RawRange>) - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Np&& __n) const + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Np&& __n) const noexcept(noexcept(views::repeat(*__range.__value_, std::min<_Dist>(ranges::distance(__range), std::forward<_Np>(__n))))) -> decltype( views::repeat(*__range.__value_, std::min<_Dist>(ranges::distance(__range), std::forward<_Np>(__n)))) { return views::repeat(*__range.__value_, std::min<_Dist>(ranges::distance(__range), std::forward<_Np>(__n))); } @@ -319,7 +319,7 @@ struct __fn { class _RawRange = remove_cvref_t<_Range>, class _Dist = range_difference_t<_Range>> requires(__is_repeat_specialization<_RawRange> && !sized_range<_RawRange>) - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Np&& __n) const + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Np&& __n) const noexcept(noexcept(views::repeat(*__range.__value_, static_cast<_Dist>(__n)))) -> decltype( views::repeat(*__range.__value_, static_cast<_Dist>(__n))) { return views::repeat(*__range.__value_, static_cast<_Dist>(__n)); } diff --git a/libcxx/include/__ranges/to.h b/libcxx/include/__ranges/to.h index 67818c521b15..8a815bce5811 100644 --- a/libcxx/include/__ranges/to.h +++ b/libcxx/include/__ranges/to.h @@ -85,7 +85,7 @@ concept __always_false = false; // `ranges::to` base template -- the `_Container` type is a simple type template parameter. template requires(!view<_Container>) -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Container to(_Range&& __range, _Args&&... __args) { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Container to(_Range&& __range, _Args&&... __args) { // Mandates: C is a cv-unqualified class type. static_assert(!is_const_v<_Container>, "The target container cannot be const-qualified, please remove the const"); static_assert( @@ -192,7 +192,7 @@ struct _Deducer { // `ranges::to` specialization -- `_Container` is a template template parameter requiring deduction to figure out the // container element type. template