llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Jakub Ficek (ficol) <details> <summary>Changes</summary> Currently only __builtin_elementwise_sqrt emits contrained fp intrinsic and propagates fp options. This commit adds this support for the rest of elementwise builtins. --- Patch is 87.20 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/166905.diff 11 Files Affected: - (modified) clang/lib/CodeGen/CGBuiltin.cpp (+35-89) - (modified) clang/test/CodeGen/constrained-math-builtins.c (+8-8) - (modified) clang/test/CodeGen/strictfp-elementwise-builtins.cpp (+74-94) - (modified) clang/test/CodeGenHLSL/builtins/exp-overloads.hlsl (+40-40) - (modified) clang/test/CodeGenHLSL/builtins/exp.hlsl (+24-24) - (modified) clang/test/CodeGenHLSL/builtins/exp2-overloads.hlsl (+40-40) - (modified) clang/test/CodeGenHLSL/builtins/exp2.hlsl (+24-24) - (modified) clang/test/CodeGenHLSL/builtins/ldexp.hlsl (+16-16) - (modified) clang/test/CodeGenHLSL/builtins/lit.hlsl (+6-6) - (modified) clang/test/CodeGenHLSL/builtins/round-overloads.hlsl (+40-40) - (modified) clang/test/CodeGenHLSL/builtins/round.hlsl (+24-24) ``````````diff diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 0a2ea416e5e4d..d97f0e0d36aa6 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -2727,6 +2727,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, case Builtin::BI__builtin_acosf16: case Builtin::BI__builtin_acosl: case Builtin::BI__builtin_acosf128: + case Builtin::BI__builtin_elementwise_acos: return RValue::get(emitUnaryMaybeConstrainedFPBuiltin( *this, E, Intrinsic::acos, Intrinsic::experimental_constrained_acos)); @@ -2738,6 +2739,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, case Builtin::BI__builtin_asinf16: case Builtin::BI__builtin_asinl: case Builtin::BI__builtin_asinf128: + case Builtin::BI__builtin_elementwise_asin: return RValue::get(emitUnaryMaybeConstrainedFPBuiltin( *this, E, Intrinsic::asin, Intrinsic::experimental_constrained_asin)); @@ -2749,6 +2751,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, case Builtin::BI__builtin_atanf16: case Builtin::BI__builtin_atanl: case Builtin::BI__builtin_atanf128: + case Builtin::BI__builtin_elementwise_atan: return RValue::get(emitUnaryMaybeConstrainedFPBuiltin( *this, E, Intrinsic::atan, Intrinsic::experimental_constrained_atan)); @@ -2760,6 +2763,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, case Builtin::BI__builtin_atan2f16: case Builtin::BI__builtin_atan2l: case Builtin::BI__builtin_atan2f128: + case Builtin::BI__builtin_elementwise_atan2: return RValue::get(emitBinaryMaybeConstrainedFPBuiltin( *this, E, Intrinsic::atan2, Intrinsic::experimental_constrained_atan2)); @@ -2772,6 +2776,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, case Builtin::BI__builtin_ceilf16: case Builtin::BI__builtin_ceill: case Builtin::BI__builtin_ceilf128: + case Builtin::BI__builtin_elementwise_ceil: return RValue::get(emitUnaryMaybeConstrainedFPBuiltin(*this, E, Intrinsic::ceil, Intrinsic::experimental_constrained_ceil)); @@ -2795,6 +2800,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, case Builtin::BI__builtin_cosf16: case Builtin::BI__builtin_cosl: case Builtin::BI__builtin_cosf128: + case Builtin::BI__builtin_elementwise_cos: return RValue::get(emitUnaryMaybeConstrainedFPBuiltin(*this, E, Intrinsic::cos, Intrinsic::experimental_constrained_cos)); @@ -2807,6 +2813,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, case Builtin::BI__builtin_coshf16: case Builtin::BI__builtin_coshl: case Builtin::BI__builtin_coshf128: + case Builtin::BI__builtin_elementwise_cosh: return RValue::get(emitUnaryMaybeConstrainedFPBuiltin( *this, E, Intrinsic::cosh, Intrinsic::experimental_constrained_cosh)); @@ -2818,6 +2825,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, case Builtin::BI__builtin_expf16: case Builtin::BI__builtin_expl: case Builtin::BI__builtin_expf128: + case Builtin::BI__builtin_elementwise_exp: return RValue::get(emitUnaryMaybeConstrainedFPBuiltin(*this, E, Intrinsic::exp, Intrinsic::experimental_constrained_exp)); @@ -2830,6 +2838,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, case Builtin::BI__builtin_exp2f16: case Builtin::BI__builtin_exp2l: case Builtin::BI__builtin_exp2f128: + case Builtin::BI__builtin_elementwise_exp2: return RValue::get(emitUnaryMaybeConstrainedFPBuiltin(*this, E, Intrinsic::exp2, Intrinsic::experimental_constrained_exp2)); @@ -2837,13 +2846,11 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, case Builtin::BI__builtin_exp10f: case Builtin::BI__builtin_exp10f16: case Builtin::BI__builtin_exp10l: - case Builtin::BI__builtin_exp10f128: { + case Builtin::BI__builtin_exp10f128: + case Builtin::BI__builtin_elementwise_exp10: // TODO: strictfp support - if (Builder.getIsFPConstrained()) - break; return RValue::get( emitBuiltinWithOneOverloadedType<1>(*this, E, Intrinsic::exp10)); - } case Builtin::BIfabs: case Builtin::BIfabsf: case Builtin::BIfabsl: @@ -2863,6 +2870,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, case Builtin::BI__builtin_floorf16: case Builtin::BI__builtin_floorl: case Builtin::BI__builtin_floorf128: + case Builtin::BI__builtin_elementwise_floor: return RValue::get(emitUnaryMaybeConstrainedFPBuiltin(*this, E, Intrinsic::floor, Intrinsic::experimental_constrained_floor)); @@ -2875,6 +2883,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, case Builtin::BI__builtin_fmaf16: case Builtin::BI__builtin_fmal: case Builtin::BI__builtin_fmaf128: + case Builtin::BI__builtin_elementwise_fma: return RValue::get(emitTernaryMaybeConstrainedFPBuiltin(*this, E, Intrinsic::fma, Intrinsic::experimental_constrained_fma)); @@ -2939,7 +2948,13 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E); Value *Arg1 = EmitScalarExpr(E->getArg(0)); Value *Arg2 = EmitScalarExpr(E->getArg(1)); - return RValue::get(Builder.CreateFRem(Arg1, Arg2, "fmod")); + if (Builder.getIsFPConstrained()) { + Function *F = CGM.getIntrinsic(Intrinsic::experimental_constrained_frem, + Arg1->getType()); + return RValue::get(Builder.CreateConstrainedFPCall(F, {Arg1, Arg2})); + } else { + return RValue::get(Builder.CreateFRem(Arg1, Arg2, "fmod")); + } } case Builtin::BIlog: @@ -2950,6 +2965,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, case Builtin::BI__builtin_logf16: case Builtin::BI__builtin_logl: case Builtin::BI__builtin_logf128: + case Builtin::BI__builtin_elementwise_log: return RValue::get(emitUnaryMaybeConstrainedFPBuiltin(*this, E, Intrinsic::log, Intrinsic::experimental_constrained_log)); @@ -2962,6 +2978,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, case Builtin::BI__builtin_log10f16: case Builtin::BI__builtin_log10l: case Builtin::BI__builtin_log10f128: + case Builtin::BI__builtin_elementwise_log10: return RValue::get(emitUnaryMaybeConstrainedFPBuiltin(*this, E, Intrinsic::log10, Intrinsic::experimental_constrained_log10)); @@ -2974,6 +2991,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, case Builtin::BI__builtin_log2f16: case Builtin::BI__builtin_log2l: case Builtin::BI__builtin_log2f128: + case Builtin::BI__builtin_elementwise_log2: return RValue::get(emitUnaryMaybeConstrainedFPBuiltin(*this, E, Intrinsic::log2, Intrinsic::experimental_constrained_log2)); @@ -2985,6 +3003,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, case Builtin::BI__builtin_nearbyintf: case Builtin::BI__builtin_nearbyintl: case Builtin::BI__builtin_nearbyintf128: + case Builtin::BI__builtin_elementwise_nearbyint: return RValue::get(emitUnaryMaybeConstrainedFPBuiltin(*this, E, Intrinsic::nearbyint, Intrinsic::experimental_constrained_nearbyint)); @@ -2997,6 +3016,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, case Builtin::BI__builtin_powf16: case Builtin::BI__builtin_powl: case Builtin::BI__builtin_powf128: + case Builtin::BI__builtin_elementwise_pow: return RValue::get(emitBinaryMaybeConstrainedFPBuiltin(*this, E, Intrinsic::pow, Intrinsic::experimental_constrained_pow)); @@ -3009,6 +3029,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, case Builtin::BI__builtin_rintf16: case Builtin::BI__builtin_rintl: case Builtin::BI__builtin_rintf128: + case Builtin::BI__builtin_elementwise_rint: return RValue::get(emitUnaryMaybeConstrainedFPBuiltin(*this, E, Intrinsic::rint, Intrinsic::experimental_constrained_rint)); @@ -3021,6 +3042,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, case Builtin::BI__builtin_roundf16: case Builtin::BI__builtin_roundl: case Builtin::BI__builtin_roundf128: + case Builtin::BI__builtin_elementwise_round: return RValue::get(emitUnaryMaybeConstrainedFPBuiltin(*this, E, Intrinsic::round, Intrinsic::experimental_constrained_round)); @@ -3033,6 +3055,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, case Builtin::BI__builtin_roundevenf16: case Builtin::BI__builtin_roundevenl: case Builtin::BI__builtin_roundevenf128: + case Builtin::BI__builtin_elementwise_roundeven: return RValue::get(emitUnaryMaybeConstrainedFPBuiltin(*this, E, Intrinsic::roundeven, Intrinsic::experimental_constrained_roundeven)); @@ -3045,6 +3068,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, case Builtin::BI__builtin_sinf16: case Builtin::BI__builtin_sinl: case Builtin::BI__builtin_sinf128: + case Builtin::BI__builtin_elementwise_sin: return RValue::get(emitUnaryMaybeConstrainedFPBuiltin(*this, E, Intrinsic::sin, Intrinsic::experimental_constrained_sin)); @@ -3057,6 +3081,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, case Builtin::BI__builtin_sinhf16: case Builtin::BI__builtin_sinhl: case Builtin::BI__builtin_sinhf128: + case Builtin::BI__builtin_elementwise_sinh: return RValue::get(emitUnaryMaybeConstrainedFPBuiltin( *this, E, Intrinsic::sinh, Intrinsic::experimental_constrained_sinh)); @@ -3104,6 +3129,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, case Builtin::BI__builtin_tanf16: case Builtin::BI__builtin_tanl: case Builtin::BI__builtin_tanf128: + case Builtin::BI__builtin_elementwise_tan: return RValue::get(emitUnaryMaybeConstrainedFPBuiltin( *this, E, Intrinsic::tan, Intrinsic::experimental_constrained_tan)); @@ -3115,6 +3141,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, case Builtin::BI__builtin_tanhf16: case Builtin::BI__builtin_tanhl: case Builtin::BI__builtin_tanhf128: + case Builtin::BI__builtin_elementwise_tanh: return RValue::get(emitUnaryMaybeConstrainedFPBuiltin( *this, E, Intrinsic::tanh, Intrinsic::experimental_constrained_tanh)); @@ -3126,6 +3153,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, case Builtin::BI__builtin_truncf16: case Builtin::BI__builtin_truncl: case Builtin::BI__builtin_truncf128: + case Builtin::BI__builtin_elementwise_trunc: return RValue::get(emitUnaryMaybeConstrainedFPBuiltin(*this, E, Intrinsic::trunc, Intrinsic::experimental_constrained_trunc)); @@ -3177,11 +3205,11 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, case Builtin::BI__builtin_ldexpf: case Builtin::BI__builtin_ldexpl: case Builtin::BI__builtin_ldexpf16: - case Builtin::BI__builtin_ldexpf128: { + case Builtin::BI__builtin_ldexpf128: + case Builtin::BI__builtin_elementwise_ldexp: return RValue::get(emitBinaryExpMaybeConstrainedFPBuiltin( *this, E, Intrinsic::ldexp, Intrinsic::experimental_constrained_ldexp)); - } default: break; } @@ -3964,100 +3992,18 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, return RValue::get(Result); } - case Builtin::BI__builtin_elementwise_acos: - return RValue::get(emitBuiltinWithOneOverloadedType<1>( - *this, E, Intrinsic::acos, "elt.acos")); - case Builtin::BI__builtin_elementwise_asin: - return RValue::get(emitBuiltinWithOneOverloadedType<1>( - *this, E, Intrinsic::asin, "elt.asin")); - case Builtin::BI__builtin_elementwise_atan: - return RValue::get(emitBuiltinWithOneOverloadedType<1>( - *this, E, Intrinsic::atan, "elt.atan")); - case Builtin::BI__builtin_elementwise_atan2: - return RValue::get(emitBuiltinWithOneOverloadedType<2>( - *this, E, Intrinsic::atan2, "elt.atan2")); - case Builtin::BI__builtin_elementwise_ceil: - return RValue::get(emitBuiltinWithOneOverloadedType<1>( - *this, E, Intrinsic::ceil, "elt.ceil")); - case Builtin::BI__builtin_elementwise_exp: - return RValue::get(emitBuiltinWithOneOverloadedType<1>( - *this, E, Intrinsic::exp, "elt.exp")); - case Builtin::BI__builtin_elementwise_exp2: - return RValue::get(emitBuiltinWithOneOverloadedType<1>( - *this, E, Intrinsic::exp2, "elt.exp2")); - case Builtin::BI__builtin_elementwise_exp10: - return RValue::get(emitBuiltinWithOneOverloadedType<1>( - *this, E, Intrinsic::exp10, "elt.exp10")); - case Builtin::BI__builtin_elementwise_ldexp: { - Value *Src = EmitScalarExpr(E->getArg(0)); - Value *Exp = EmitScalarExpr(E->getArg(1)); - Value *Result = Builder.CreateLdexp(Src, Exp, {}, "elt.ldexp"); - return RValue::get(Result); - } - case Builtin::BI__builtin_elementwise_log: - return RValue::get(emitBuiltinWithOneOverloadedType<1>( - *this, E, Intrinsic::log, "elt.log")); - case Builtin::BI__builtin_elementwise_log2: - return RValue::get(emitBuiltinWithOneOverloadedType<1>( - *this, E, Intrinsic::log2, "elt.log2")); - case Builtin::BI__builtin_elementwise_log10: - return RValue::get(emitBuiltinWithOneOverloadedType<1>( - *this, E, Intrinsic::log10, "elt.log10")); - case Builtin::BI__builtin_elementwise_pow: { - return RValue::get( - emitBuiltinWithOneOverloadedType<2>(*this, E, Intrinsic::pow)); - } case Builtin::BI__builtin_elementwise_bitreverse: return RValue::get(emitBuiltinWithOneOverloadedType<1>( *this, E, Intrinsic::bitreverse, "elt.bitreverse")); - case Builtin::BI__builtin_elementwise_cos: - return RValue::get(emitBuiltinWithOneOverloadedType<1>( - *this, E, Intrinsic::cos, "elt.cos")); - case Builtin::BI__builtin_elementwise_cosh: - return RValue::get(emitBuiltinWithOneOverloadedType<1>( - *this, E, Intrinsic::cosh, "elt.cosh")); - case Builtin::BI__builtin_elementwise_floor: - return RValue::get(emitBuiltinWithOneOverloadedType<1>( - *this, E, Intrinsic::floor, "elt.floor")); case Builtin::BI__builtin_elementwise_popcount: return RValue::get(emitBuiltinWithOneOverloadedType<1>( *this, E, Intrinsic::ctpop, "elt.ctpop")); - case Builtin::BI__builtin_elementwise_roundeven: - return RValue::get(emitBuiltinWithOneOverloadedType<1>( - *this, E, Intrinsic::roundeven, "elt.roundeven")); - case Builtin::BI__builtin_elementwise_round: - return RValue::get(emitBuiltinWithOneOverloadedType<1>( - *this, E, Intrinsic::round, "elt.round")); - case Builtin::BI__builtin_elementwise_rint: - return RValue::get(emitBuiltinWithOneOverloadedType<1>( - *this, E, Intrinsic::rint, "elt.rint")); - case Builtin::BI__builtin_elementwise_nearbyint: - return RValue::get(emitBuiltinWithOneOverloadedType<1>( - *this, E, Intrinsic::nearbyint, "elt.nearbyint")); - case Builtin::BI__builtin_elementwise_sin: - return RValue::get(emitBuiltinWithOneOverloadedType<1>( - *this, E, Intrinsic::sin, "elt.sin")); - case Builtin::BI__builtin_elementwise_sinh: - return RValue::get(emitBuiltinWithOneOverloadedType<1>( - *this, E, Intrinsic::sinh, "elt.sinh")); - case Builtin::BI__builtin_elementwise_tan: - return RValue::get(emitBuiltinWithOneOverloadedType<1>( - *this, E, Intrinsic::tan, "elt.tan")); - case Builtin::BI__builtin_elementwise_tanh: - return RValue::get(emitBuiltinWithOneOverloadedType<1>( - *this, E, Intrinsic::tanh, "elt.tanh")); - case Builtin::BI__builtin_elementwise_trunc: - return RValue::get(emitBuiltinWithOneOverloadedType<1>( - *this, E, Intrinsic::trunc, "elt.trunc")); case Builtin::BI__builtin_elementwise_canonicalize: return RValue::get(emitBuiltinWithOneOverloadedType<1>( *this, E, Intrinsic::canonicalize, "elt.canonicalize")); case Builtin::BI__builtin_elementwise_copysign: return RValue::get( emitBuiltinWithOneOverloadedType<2>(*this, E, Intrinsic::copysign)); - case Builtin::BI__builtin_elementwise_fma: - return RValue::get( - emitBuiltinWithOneOverloadedType<3>(*this, E, Intrinsic::fma)); case Builtin::BI__builtin_elementwise_fshl: return RValue::get( emitBuiltinWithOneOverloadedType<3>(*this, E, Intrinsic::fshl)); diff --git a/clang/test/CodeGen/constrained-math-builtins.c b/clang/test/CodeGen/constrained-math-builtins.c index 68b9e75283c54..30fd896bb6489 100644 --- a/clang/test/CodeGen/constrained-math-builtins.c +++ b/clang/test/CodeGen/constrained-math-builtins.c @@ -101,10 +101,10 @@ __builtin_atan2(f,f); __builtin_atan2f(f,f); __builtin_atan2l(f,f); __builtin_exp10(f); __builtin_exp10f(f); __builtin_exp10l(f); __builtin_exp10f128(f); -// CHECK: call double @exp10(double noundef %{{.*}}) -// CHECK: call float @exp10f(float noundef %{{.*}}) -// CHECK: call x86_fp80 @exp10l(x86_fp80 noundef %{{.*}}) -// CHECK: call fp128 @exp10f128(fp128 noundef %{{.*}}) +// CHECK: call double @llvm.exp10.f64(double %{{.*}}) +// CHECK: call float @llvm.exp10.f32(float %{{.*}}) +// CHECK: call x86_fp80 @llvm.exp10.f80(x86_fp80 %{{.*}}) +// CHECK: call fp128 @llvm.exp10.f128(fp128 %{{.*}}) __builtin_floor(f); __builtin_floorf(f); __builtin_floorl(f); __builtin_floorf128(f); @@ -287,10 +287,10 @@ __builtin_atan2(f,f); __builtin_atan2f(f,f); __builtin_atan2l(f,f); // CHECK: declare x86_fp80 @llvm.experimental.constrained.exp2.f80(x86_fp80, metadata, metadata) // CHECK: declare fp128 @llvm.experimental.constrained.exp2.f128(fp128, metadata, metadata) -// CHECK: declare double @exp10(double noundef) -// CHECK: declare float @exp10f(float noundef) -// CHECK: declare x86_fp80 @exp10l(x86_fp80 noundef) -// CHECK: declare fp128 @exp10f128(fp128 noundef) +// CHECK: declare double @llvm.exp10.f64(double) +// CHECK: declare float @llvm.exp10.f32(float) +// CHECK: declare x86_fp80 @llvm.exp10.f80(x86_fp80) +// CHECK: declare fp128 @llvm.exp10.f128(fp128) // CHECK: declare double @llvm.experimental.constrained.floor.f64(double, metadata) // CHECK: declare float @llvm.experimental.constrained.floor.f32(float, metadata) diff --git a/clang/test/CodeGen/strictfp-elementwise-builtins.cpp b/clang/test/CodeGen/strictfp-elementwise-builtins.cpp index b250512efc5c7..cb5edb5744bbb 100644 --- a/clang/test/CodeGen/strictfp-elementwise-builtins.cpp +++ b/clang/test/CodeGen/strictfp-elementwise-builtins.cpp @@ -68,60 +68,60 @@... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/166905 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
