diff --git a/clang/docs/ClangCommandLineReference.rst b/clang/docs/ClangCommandLineReference.rst --- a/clang/docs/ClangCommandLineReference.rst +++ b/clang/docs/ClangCommandLineReference.rst @@ -2222,6 +2222,10 @@ Enable optimizations based on the strict rules for overwriting polymorphic C++ objects +.. option:: -fstrict-pointer-alignment, -fno-strict-pointer-alignment + +Enable optimizations based on the strict rules for pointer alignment + .. option:: -fstruct-path-tbaa, -fno-struct-path-tbaa .. option:: -fsymbol-partition= diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -54,6 +54,10 @@ to allow codebases to be cleaned up in preparation for this optimization, to avoid miscompiles. +- Clang now assumes that all function pointer arguments are properly aligned, + and optimizes on that. A new ``-fstrict-pointer-alignment`` flag was + introduces (default on), which guards these new optimizations. + Improvements to Clang's diagnostics ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst --- a/clang/docs/UsersManual.rst +++ b/clang/docs/UsersManual.rst @@ -1669,6 +1669,12 @@ modules where it isn't necessary. It causes more inline virtual functions to be emitted. +.. option:: -fstrict-pointer-alignment + + Enable optimizations based on the strict rules for pointer alignment. + This currently only affects function pointer arguments, and only controls + UBSan behaviour, no optimizations are currently performed based on it. + .. option:: -fno-assume-sane-operator-new Don't assume that the C++'s new operator is sane. diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -261,6 +261,7 @@ CODEGENOPT(FineGrainedBitfieldAccesses, 1, 0) ///< Enable fine-grained bitfield accesses. CODEGENOPT(StrictEnums , 1, 0) ///< Optimize based on strict enum definition. CODEGENOPT(StrictVTablePointers, 1, 0) ///< Optimize based on the strict vtable pointers +CODEGENOPT(StrictPointerAlignment, 1, 1) ///< Optimize based on the strict pointer alignment rules CODEGENOPT(TimePasses , 1, 0) ///< Set when -ftime-report or -ftime-report= is enabled. CODEGENOPT(TimePassesPerRun , 1, 0) ///< Set when -ftime-report=per-pass-run is enabled. CODEGENOPT(TimeTrace , 1, 0) ///< Set when -ftime-trace is enabled. diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -2446,6 +2446,11 @@ PosFlag, NegFlag>; +defm strict_pointer_alignment : BoolFOption<"strict-pointer-alignment", + CodeGenOpts<"StrictPointerAlignment">, DefaultFalse, + NegFlag, + PosFlag, + BothFlags<[], " optimizations based on the strict rules for pointer alignmen">>; def fstrict_overflow : Flag<["-"], "fstrict-overflow">, Group; def fsyntax_only : Flag<["-"], "fsyntax-only">, Flags<[NoXarchOption,CoreOption,CC1Option,FC1Option]>, Group; diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -2446,6 +2446,17 @@ } } + if (getCodeGenOpts().StrictPointerAlignment) { + if (const auto *PtrTy = ParamType->getAs()) { + QualType PTy = PtrTy->getPointeeType(); + if (PTy->isObjectType()) { + llvm::Align Alignment = + getNaturalPointeeTypeAlignment(ParamType).getAsAlign(); + Attrs.addAlignmentAttr(Alignment); + } + } + } + switch (FI.getExtParameterInfo(ArgNo).getABI()) { case ParameterABI::Ordinary: break; diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -4872,6 +4872,10 @@ options::OPT_fno_force_emit_vtables, false)) CmdArgs.push_back("-fforce-emit-vtables"); + if (Args.hasFlag(options::OPT_fstrict_pointer_alignment, + options::OPT_fno_strict_pointer_alignment, + !RawTriple.isOSDarwin())) + CmdArgs.push_back("-fstrict-pointer-alignment"); if (!Args.hasFlag(options::OPT_foptimize_sibling_calls, options::OPT_fno_optimize_sibling_calls)) CmdArgs.push_back("-mdisable-tail-calls");