FreddyYe created this revision. FreddyYe requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
When __builtin_mul_overflow has input combination of (signed, signed, unsigned*) and arbitary width is larger than 64 bits, it will also generate i256 in backend. Disallow it before we improve in backend. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D107420 Files: clang/include/clang/Basic/DiagnosticSemaKinds.td clang/lib/Sema/SemaChecking.cpp clang/test/Sema/builtins-overflow.c Index: clang/test/Sema/builtins-overflow.c =================================================================== --- clang/test/Sema/builtins-overflow.c +++ clang/test/Sema/builtins-overflow.c @@ -38,4 +38,10 @@ _ExtInt(129) result; _Bool status = __builtin_mul_overflow(x, y, &result); // expected-error {{__builtin_mul_overflow does not support signed _ExtInt operands of more than 128 bits}} } + { + _ExtInt(128) x = 1; + _ExtInt(128) y = 1; + unsigned _ExtInt(128) result; + _Bool status = __builtin_mul_overflow(x, y, &result); // expected-error {{__builtin_mul_overflow does not support special combination operands (signed, signed, unsigned*) of more than 64 bits}} + } } Index: clang/lib/Sema/SemaChecking.cpp =================================================================== --- clang/lib/Sema/SemaChecking.cpp +++ clang/lib/Sema/SemaChecking.cpp @@ -328,15 +328,35 @@ // Disallow signed ExtIntType args larger than 128 bits to mul function until // we improve backend support. if (BuiltinID == Builtin::BI__builtin_mul_overflow) { - for (unsigned I = 0; I < 3; ++I) { - const auto Arg = TheCall->getArg(I); - // Third argument will be a pointer. - auto Ty = I < 2 ? Arg->getType() : Arg->getType()->getPointeeType(); - if (Ty->isExtIntType() && Ty->isSignedIntegerType() && - S.getASTContext().getIntWidth(Ty) > 128) - return S.Diag(Arg->getBeginLoc(), - diag::err_overflow_builtin_ext_int_max_size) - << 128; + const auto LeftTy = TheCall->getArg(0)->getType(); + const auto RightTy = TheCall->getArg(1)->getType(); + const auto ResultTy = TheCall->getArg(2)->getType()->getPointeeType(); + // Input compination below will also emit integer value larger than + // 128 bits in backend, disallow same as above. + if (LeftTy->isSignedIntegerType() && + S.getASTContext().getIntWidth(LeftTy) > 64 && + RightTy->isSignedIntegerType() && + S.getASTContext().getIntWidth(RightTy) > 64 && + !ResultTy->isSignedIntegerType() && + S.getASTContext().getIntWidth(ResultTy) > 64) { + return S.Diag(TheCall->getArg(0)->getBeginLoc(), + diag::err_overflow_builtin_special_combination_max_size) + << 64; + } + else if ((LeftTy->isExtIntType() && LeftTy->isSignedIntegerType() && + S.getASTContext().getIntWidth(LeftTy) > 128)) { + return S.Diag(TheCall->getArg(0)->getBeginLoc(), + diag::err_overflow_builtin_ext_int_max_size) << 128; + } + else if ((RightTy->isExtIntType() && RightTy->isSignedIntegerType() && + S.getASTContext().getIntWidth(RightTy) > 128)) { + return S.Diag(TheCall->getArg(1)->getBeginLoc(), + diag::err_overflow_builtin_ext_int_max_size) << 128; + } + else if ((ResultTy->isExtIntType() && ResultTy->isSignedIntegerType() && + S.getASTContext().getIntWidth(ResultTy) > 128)) { + return S.Diag(TheCall->getArg(2)->getBeginLoc(), + diag::err_overflow_builtin_ext_int_max_size) << 128; } } Index: clang/include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- clang/include/clang/Basic/DiagnosticSemaKinds.td +++ clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -8348,6 +8348,9 @@ def err_overflow_builtin_ext_int_max_size : Error< "__builtin_mul_overflow does not support signed _ExtInt operands of more " "than %0 bits">; +def err_overflow_builtin_special_combination_max_size : Error< + "__builtin_mul_overflow does not support special combination operands (signed, signed, unsigned*) " + "of more than %0 bits">; def err_atomic_load_store_uses_lib : Error< "atomic %select{load|store}0 requires runtime support that is not "
Index: clang/test/Sema/builtins-overflow.c =================================================================== --- clang/test/Sema/builtins-overflow.c +++ clang/test/Sema/builtins-overflow.c @@ -38,4 +38,10 @@ _ExtInt(129) result; _Bool status = __builtin_mul_overflow(x, y, &result); // expected-error {{__builtin_mul_overflow does not support signed _ExtInt operands of more than 128 bits}} } + { + _ExtInt(128) x = 1; + _ExtInt(128) y = 1; + unsigned _ExtInt(128) result; + _Bool status = __builtin_mul_overflow(x, y, &result); // expected-error {{__builtin_mul_overflow does not support special combination operands (signed, signed, unsigned*) of more than 64 bits}} + } } Index: clang/lib/Sema/SemaChecking.cpp =================================================================== --- clang/lib/Sema/SemaChecking.cpp +++ clang/lib/Sema/SemaChecking.cpp @@ -328,15 +328,35 @@ // Disallow signed ExtIntType args larger than 128 bits to mul function until // we improve backend support. if (BuiltinID == Builtin::BI__builtin_mul_overflow) { - for (unsigned I = 0; I < 3; ++I) { - const auto Arg = TheCall->getArg(I); - // Third argument will be a pointer. - auto Ty = I < 2 ? Arg->getType() : Arg->getType()->getPointeeType(); - if (Ty->isExtIntType() && Ty->isSignedIntegerType() && - S.getASTContext().getIntWidth(Ty) > 128) - return S.Diag(Arg->getBeginLoc(), - diag::err_overflow_builtin_ext_int_max_size) - << 128; + const auto LeftTy = TheCall->getArg(0)->getType(); + const auto RightTy = TheCall->getArg(1)->getType(); + const auto ResultTy = TheCall->getArg(2)->getType()->getPointeeType(); + // Input compination below will also emit integer value larger than + // 128 bits in backend, disallow same as above. + if (LeftTy->isSignedIntegerType() && + S.getASTContext().getIntWidth(LeftTy) > 64 && + RightTy->isSignedIntegerType() && + S.getASTContext().getIntWidth(RightTy) > 64 && + !ResultTy->isSignedIntegerType() && + S.getASTContext().getIntWidth(ResultTy) > 64) { + return S.Diag(TheCall->getArg(0)->getBeginLoc(), + diag::err_overflow_builtin_special_combination_max_size) + << 64; + } + else if ((LeftTy->isExtIntType() && LeftTy->isSignedIntegerType() && + S.getASTContext().getIntWidth(LeftTy) > 128)) { + return S.Diag(TheCall->getArg(0)->getBeginLoc(), + diag::err_overflow_builtin_ext_int_max_size) << 128; + } + else if ((RightTy->isExtIntType() && RightTy->isSignedIntegerType() && + S.getASTContext().getIntWidth(RightTy) > 128)) { + return S.Diag(TheCall->getArg(1)->getBeginLoc(), + diag::err_overflow_builtin_ext_int_max_size) << 128; + } + else if ((ResultTy->isExtIntType() && ResultTy->isSignedIntegerType() && + S.getASTContext().getIntWidth(ResultTy) > 128)) { + return S.Diag(TheCall->getArg(2)->getBeginLoc(), + diag::err_overflow_builtin_ext_int_max_size) << 128; } } Index: clang/include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- clang/include/clang/Basic/DiagnosticSemaKinds.td +++ clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -8348,6 +8348,9 @@ def err_overflow_builtin_ext_int_max_size : Error< "__builtin_mul_overflow does not support signed _ExtInt operands of more " "than %0 bits">; +def err_overflow_builtin_special_combination_max_size : Error< + "__builtin_mul_overflow does not support special combination operands (signed, signed, unsigned*) " + "of more than %0 bits">; def err_atomic_load_store_uses_lib : Error< "atomic %select{load|store}0 requires runtime support that is not "
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits