summaryrefslogtreecommitdiffstats
path: root/clang/test/CodeGenCXX/auto-var-init.cpp
Commit message (Collapse)AuthorAgeFilesLines
* Revert "Revert "As a follow-up to my initial mail to llvm-dev here's a first ↵Eric Christopher2019-11-261-6/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | pass at the O1 described there."" This reapplies: 8ff85ed905a7306977d07a5cd67ab4d5a56fafb4 Original commit message: As a follow-up to my initial mail to llvm-dev here's a first pass at the O1 described there. This change doesn't include any change to move from selection dag to fast isel and that will come with other numbers that should help inform that decision. There also haven't been any real debuggability studies with this pipeline yet, this is just the initial start done so that people could see it and we could start tweaking after. Test updates: Outside of the newpm tests most of the updates are coming from either optimization passes not run anymore (and without a compelling argument at the moment) that were largely used for canonicalization in clang. Original post: http://lists.llvm.org/pipermail/llvm-dev/2019-April/131494.html Tags: #llvm Differential Revision: https://reviews.llvm.org/D65410 This reverts commit c9ddb02659e3ece7a0d9d6b4dac7ceea4ae46e6d.
* Revert "As a follow-up to my initial mail to llvm-dev here's a first pass at ↵Muhammad Omair Javaid2019-11-261-3/+6
| | | | | | | | | | | | | | | | | | | | | | | the O1 described there." This reverts commit 8ff85ed905a7306977d07a5cd67ab4d5a56fafb4. This commit introduced 9 new failures on lldb buildbot host at http://lab.llvm.org:8014/builders/lldb-aarch64-ubuntu Following tests were failing: lldb-api :: functionalities/tail_call_frames/ambiguous_tail_call_seq1/TestAmbiguousTailCallSeq1.py lldb-api :: functionalities/tail_call_frames/ambiguous_tail_call_seq2/TestAmbiguousTailCallSeq2.py lldb-api :: functionalities/tail_call_frames/disambiguate_call_site/TestDisambiguateCallSite.py lldb-api :: functionalities/tail_call_frames/disambiguate_paths_to_common_sink/TestDisambiguatePathsToCommonSink.py lldb-api :: functionalities/tail_call_frames/disambiguate_tail_call_seq/TestDisambiguateTailCallSeq.py lldb-api :: functionalities/tail_call_frames/inlining_and_tail_calls/TestInliningAndTailCalls.py lldb-api :: functionalities/tail_call_frames/sbapi_support/TestTailCallFrameSBAPI.py lldb-api :: functionalities/tail_call_frames/thread_step_out_message/TestArtificialFrameStepOutMessage.py lldb-api :: functionalities/tail_call_frames/thread_step_out_or_return/TestSteppingOutWithArtificialFrames.py lldb-api :: functionalities/tail_call_frames/unambiguous_sequence/TestUnambiguousTailCalls.py Tags: #llvm Differential Revision: https://reviews.llvm.org/D65410
* As a follow-up to my initial mail to llvm-dev here's a first pass at the O1 ↵Eric Christopher2019-11-251-6/+3
| | | | | | | | | | | | | | | | | | | | | described there. This change doesn't include any change to move from selection dag to fast isel and that will come with other numbers that should help inform that decision. There also haven't been any real debuggability studies with this pipeline yet, this is just the initial start done so that people could see it and we could start tweaking after. Test updates: Outside of the newpm tests most of the updates are coming from either optimization passes not run anymore (and without a compelling argument at the moment) that were largely used for canonicalization in clang. Original post: http://lists.llvm.org/pipermail/llvm-dev/2019-April/131494.html Tags: #llvm Differential Revision: https://reviews.llvm.org/D65410
* [clang][codegen][NFC] Make test patterns more permissive.Clement Courbet2019-09-101-2/+1
| | | | | | | See the discussion in: http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20190909/692736.html llvm-svn: 371522
* [NFC] Updated tests after r368657David Bolvansky2019-08-131-2/+2
| | | | llvm-svn: 368658
* CodeGet: Init 32bit pointers with 0xFFFFFFFFVitaly Buka2019-07-121-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Summary: Patch makes D63967 effective for 32bit platforms and improves pattern initialization there. It cuts size of 32bit binary compiled with -ftrivial-auto-var-init=pattern by 2% (3% with -Os). Binary size change on CTMark, (with -fuse-ld=lld -Wl,--icf=all, similar results with default linker options) ``` master patch diff Os pattern 7.915580e+05 7.698424e+05 -0.028387 O3 pattern 9.953688e+05 9.752952e+05 -0.019325 ``` Zero vs Pattern on master ``` zero pattern diff Os 7.689712e+05 7.915580e+05 0.031380 O3 9.744796e+05 9.953688e+05 0.021133 ``` Zero vs Pattern with the patch ``` zero pattern diff Os 7.689712e+05 7.698424e+05 0.000789 O3 9.744796e+05 9.752952e+05 0.000742 ``` Reviewers: pcc, eugenis, glider, jfb Reviewed By: jfb Subscribers: hubert.reinterpretcast, dexonsmith, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D64597 llvm-svn: 365921
* Handle IntToPtr in isBytewiseValueVitaly Buka2019-07-121-8/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Summary: This helps with more efficient use of memset for pattern initialization From @pcc prototype for -ftrivial-auto-var-init=pattern optimizations Binary size change on CTMark, (with -fuse-ld=lld -Wl,--icf=all, similar results with default linker options) ``` master patch diff Os 8.238864e+05 8.238864e+05 0.0 O3 1.054797e+06 1.054797e+06 0.0 Os zero 8.292384e+05 8.292384e+05 0.0 O3 zero 1.062626e+06 1.062626e+06 0.0 Os pattern 8.579712e+05 8.338048e+05 -0.030299 O3 pattern 1.090502e+06 1.067574e+06 -0.020481 ``` Zero vs Pattern on master ``` zero pattern diff Os 8.292384e+05 8.579712e+05 0.036578 O3 1.062626e+06 1.090502e+06 0.025124 ``` Zero vs Pattern with the patch ``` zero pattern diff Os 8.292384e+05 8.338048e+05 0.003333 O3 1.062626e+06 1.067574e+06 0.003193 ``` Reviewers: pcc, eugenis Subscribers: hiraditya, cfe-commits, llvm-commits Tags: #clang, #llvm Differential Revision: https://reviews.llvm.org/D63967 llvm-svn: 365858
* Codegen, NFC: 32bit test in auto-var-init.cppVitaly Buka2019-07-121-115/+107
| | | | llvm-svn: 365857
* CodeGen: Suppress c++ warnings in testVitaly Buka2019-07-111-0/+2
| | | | llvm-svn: 365835
* CodeGen, NFC: Test for auto-init for 32bit pointersVitaly Buka2019-07-111-0/+16
| | | | llvm-svn: 365822
* [clang][NewPM] Add -fno-experimental-new-pass-manager to testsLeonard Chan2019-06-211-7/+18
| | | | | | | | | | | | | | | | As per the discussion on D58375, we disable test that have optimizations under the new PM. This patch adds -fno-experimental-new-pass-manager to RUNS that: - Already run with optimizations (-O1 or higher) that were missed in D58375. - Explicitly test new PM behavior along side some new PM RUNS, but are missing this flag if new PM is enabled by default. - Specify -O without the number. Based on getOptimizationLevel(), it seems the default is 2, and the IR appears to be the same when changed to -O2, so update the test to explicitly say -O2 and provide -fno-experimental-new-pass-manager`. Differential Revision: https://reviews.llvm.org/D63156 llvm-svn: 364066
* Fix auto-init testJF Bastien2019-04-301-3/+3
| | | | | | r359628 changed the initialization of padding to follow C, but I didn't update the C++ tests. llvm-svn: 359636
* CodeGen: Preserve packed attribute in constStructWithPadding.Peter Collingbourne2019-03-161-0/+6
| | | | | | | | Otherwise the object may have an incorrect size due to tail padding. Differential Revision: https://reviews.llvm.org/D59446 llvm-svn: 356328
* Variable auto-init: split out small arraysJF Bastien2019-03-081-9/+15
| | | | | | | | | | | | | | | | | | Summary: Following up with r355181, initialize small arrays as well. LLVM stage2 shows a tiny size gain. <rdar://48523005> Reviewers: glider, pcc, kcc, rjmccall Subscribers: jkorous, dexonsmith, jdoerfert, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58885 llvm-svn: 355660
* CodeGen: Fix PR40605 by splitting constant struct initializersAlexander Potapenko2019-03-011-160/+293
| | | | | | | | | | | | | | When emitting initializers for local structures for code built with -ftrivial-auto-var-init, replace constant structures with sequences of stores. This appears to greatly help removing dead initialization stores to those locals that are later overwritten by other data. This also removes a lot of .rodata constants (see PR40605), replacing most of them with immediate values (for Linux kernel the .rodata size is reduced by ~1.9%) llvm-svn: 355181
* CodeGen: Explicitly initialize structure padding in the ↵Alexander Potapenko2019-02-261-14/+122
| | | | | | | | | | | | | | | -ftrivial-auto-var-init mode When generating initializers for local structures in the -ftrivial-auto-var-init mode, explicitly wipe the padding bytes with either 0x00 or 0xAA. This will allow us to automatically handle the padding when splitting the initialization stores (see https://reviews.llvm.org/D57898). Reviewed at https://reviews.llvm.org/D58188 llvm-svn: 354861
* [NFC] Reorder some mis-ordered testsJF Bastien2019-02-251-4/+4
| | | | | | I somehow had misaligned some of the tests when I originally wrote this. Re-order them properly. llvm-svn: 354831
* [NFC] Explicitly add -std=c++14 option to tests that rely on the C++14 defaultNemanja Ivanovic2019-02-051-3/+3
| | | | | | | | | | | When Clang/LLVM is built with the CLANG_DEFAULT_STD_CXX CMake macro that sets the default standard to something other than C++14, there are a number of lit tests that fail as they rely on the C++14 default. This patch just adds the language standard option explicitly to such test cases. Differential revision: https://reviews.llvm.org/D57581 llvm-svn: 353163
* Automatic variable initializationJF Bastien2018-12-181-2/+334
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Summary: Add an option to initialize automatic variables with either a pattern or with zeroes. The default is still that automatic variables are uninitialized. Also add attributes to request uninitialized on a per-variable basis, mainly to disable initialization of large stack arrays when deemed too expensive. This isn't meant to change the semantics of C and C++. Rather, it's meant to be a last-resort when programmers inadvertently have some undefined behavior in their code. This patch aims to make undefined behavior hurt less, which security-minded people will be very happy about. Notably, this means that there's no inadvertent information leak when: - The compiler re-uses stack slots, and a value is used uninitialized. - The compiler re-uses a register, and a value is used uninitialized. - Stack structs / arrays / unions with padding are copied. This patch only addresses stack and register information leaks. There's many more infoleaks that we could address, and much more undefined behavior that could be tamed. Let's keep this patch focused, and I'm happy to address related issues elsewhere. To keep the patch simple, only some `undef` is removed for now, see `replaceUndef`. The padding-related infoleaks are therefore not all gone yet. This will be addressed in a follow-up, mainly because addressing padding-related leaks should be a stand-alone option which is implied by variable initialization. There are three options when it comes to automatic variable initialization: 0. Uninitialized This is C and C++'s default. It's not changing. Depending on code generation, a programmer who runs into undefined behavior by using an uninialized automatic variable may observe any previous value (including program secrets), or any value which the compiler saw fit to materialize on the stack or in a register (this could be to synthesize an immediate, to refer to code or data locations, to generate cookies, etc). 1. Pattern initialization This is the recommended initialization approach. Pattern initialization's goal is to initialize automatic variables with values which will likely transform logic bugs into crashes down the line, are easily recognizable in a crash dump, without being values which programmers can rely on for useful program semantics. At the same time, pattern initialization tries to generate code which will optimize well. You'll find the following details in `patternFor`: - Integers are initialized with repeated 0xAA bytes (infinite scream). - Vectors of integers are also initialized with infinite scream. - Pointers are initialized with infinite scream on 64-bit platforms because it's an unmappable pointer value on architectures I'm aware of. Pointers are initialize to 0x000000AA (small scream) on 32-bit platforms because 32-bit platforms don't consistently offer unmappable pages. When they do it's usually the zero page. As people try this out, I expect that we'll want to allow different platforms to customize this, let's do so later. - Vectors of pointers are initialized the same way pointers are. - Floating point values and vectors are initialized with a negative quiet NaN with repeated 0xFF payload (e.g. 0xffffffff and 0xffffffffffffffff). NaNs are nice (here, anways) because they propagate on arithmetic, making it more likely that entire computations become NaN when a single uninitialized value sneaks in. - Arrays are initialized to their homogeneous elements' initialization value, repeated. Stack-based Variable-Length Arrays (VLAs) are runtime-initialized to the allocated size (no effort is made for negative size, but zero-sized VLAs are untouched even if technically undefined). - Structs are initialized to their heterogeneous element's initialization values. Zero-size structs are initialized as 0xAA since they're allocated a single byte. - Unions are initialized using the initialization for the largest member of the union. Expect the values used for pattern initialization to change over time, as we refine heuristics (both for performance and security). The goal is truly to avoid injecting semantics into undefined behavior, and we should be comfortable changing these values when there's a worthwhile point in doing so. Why so much infinite scream? Repeated byte patterns tend to be easy to synthesize on most architectures, and otherwise memset is usually very efficient. For values which aren't entirely repeated byte patterns, LLVM will often generate code which does memset + a few stores. 2. Zero initialization Zero initialize all values. This has the unfortunate side-effect of providing semantics to otherwise undefined behavior, programs therefore might start to rely on this behavior, and that's sad. However, some programmers believe that pattern initialization is too expensive for them, and data might show that they're right. The only way to make these programmers wrong is to offer zero-initialization as an option, figure out where they are right, and optimize the compiler into submission. Until the compiler provides acceptable performance for all security-minded code, zero initialization is a useful (if blunt) tool. I've been asked for a fourth initialization option: user-provided byte value. This might be useful, and can easily be added later. Why is an out-of band initialization mecanism desired? We could instead use -Wuninitialized! Indeed we could, but then we're forcing the programmer to provide semantics for something which doesn't actually have any (it's uninitialized!). It's then unclear whether `int derp = 0;` lends meaning to `0`, or whether it's just there to shut that warning up. It's also way easier to use a compiler flag than it is to manually and intelligently initialize all values in a program. Why not just rely on static analysis? Because it cannot reason about all dynamic code paths effectively, and it has false positives. It's a great tool, could get even better, but it's simply incapable of catching all uses of uninitialized values. Why not just rely on memory sanitizer? Because it's not universally available, has a 3x performance cost, and shouldn't be deployed in production. Again, it's a great tool, it'll find the dynamic uses of uninitialized variables that your test coverage hits, but it won't find the ones that you encounter in production. What's the performance like? Not too bad! Previous publications [0] have cited 2.7 to 4.5% averages. We've commmitted a few patches over the last few months to address specific regressions, both in code size and performance. In all cases, the optimizations are generally useful, but variable initialization benefits from them a lot more than regular code does. We've got a handful of other optimizations in mind, but the code is in good enough shape and has found enough latent issues that it's a good time to get the change reviewed, checked in, and have others kick the tires. We'll continue reducing overheads as we try this out on diverse codebases. Is it a good idea? Security-minded folks think so, and apparently so does the Microsoft Visual Studio team [1] who say "Between 2017 and mid 2018, this feature would have killed 49 MSRC cases that involved uninitialized struct data leaking across a trust boundary. It would have also mitigated a number of bugs involving uninitialized struct data being used directly.". They seem to use pure zero initialization, and claim to have taken the overheads down to within noise. Don't just trust Microsoft though, here's another relevant person asking for this [2]. It's been proposed for GCC [3] and LLVM [4] before. What are the caveats? A few! - Variables declared in unreachable code, and used later, aren't initialized. This goto, Duff's device, other objectionable uses of switch. This should instead be a hard-error in any serious codebase. - Volatile stack variables are still weird. That's pre-existing, it's really the language's fault and this patch keeps it weird. We should deprecate volatile [5]. - As noted above, padding isn't fully handled yet. I don't think these caveats make the patch untenable because they can be addressed separately. Should this be on by default? Maybe, in some circumstances. It's a conversation we can have when we've tried it out sufficiently, and we're confident that we've eliminated enough of the overheads that most codebases would want to opt-in. Let's keep our precious undefined behavior until that point in time. How do I use it: 1. On the command-line: -ftrivial-auto-var-init=uninitialized (the default) -ftrivial-auto-var-init=pattern -ftrivial-auto-var-init=zero -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang 2. Using an attribute: int dont_initialize_me __attribute((uninitialized)); [0]: https://users.elis.ugent.be/~jsartor/researchDocs/OOPSLA2011Zero-submit.pdf [1]: https://twitter.com/JosephBialek/status/1062774315098112001 [2]: https://outflux.net/slides/2018/lss/danger.pdf [3]: https://gcc.gnu.org/ml/gcc-patches/2014-06/msg00615.html [4]: https://github.com/AndroidHardeningArchive/platform_external_clang/commit/776a0955ef6686d23a82d2e6a3cbd4a6a882c31c [5]: http://wg21.link/p1152 I've also posted an RFC to cfe-dev: http://lists.llvm.org/pipermail/cfe-dev/2018-November/060172.html <rdar://problem/39131435> Reviewers: pcc, kcc, rsmith Subscribers: JDevlieghere, jkorous, dexonsmith, cfe-commits Differential Revision: https://reviews.llvm.org/D54604 llvm-svn: 349442
* CDDecl More automatic variable tail padding testJF Bastien2018-08-081-1/+20
| | | | | | Test tail padded automatic variable at different width, because they encounter different codegen. llvm-svn: 339273
* [NFC] Improve auto-var-init alignment checkJF Bastien2018-08-071-215/+215
| | | | | | We're not actually testing for alignment, we just want to know that whatever incoming alignment got propagated. Do that by capturing the alignment and checking that it's actually what's passed later, instead of hard-coding an alignment value. llvm-svn: 339196
* Auto var init test fix #2JF Bastien2018-08-071-15/+15
| | | | | | It turns out that the AVX bots have different alignment for their vectors, and my test mistakenly assumed a particular vector alignent on the stack. Instead, capture the alignment and test for it in subsequent operations. llvm-svn: 339093
* Remove broken command flagJF Bastien2018-08-071-1/+1
| | | | | | I was using it for testing, r339089 shouldn't have contained it. llvm-svn: 339090
* [NFC] Test automatic variable initializationJF Bastien2018-08-071-0/+999
Summary: r337887 started using memset for automatic variable initialization where sensible. A follow-up discussion leads me to believe that we should better test automatic variable initialization, and that there are probably follow-up patches in clang and LLVM to improve codegen. It’ll be important to measure -O0 compile time, and figure out which transforms should be in the frontend versus the backend. This patch is just a test of the current behavior, no questions asked. Follow-up patches will tune the code generation. <rdar://problem/42981573> Subscribers: dexonsmith, cfe-commits Differential Revision: https://reviews.llvm.org/D50361 llvm-svn: 339089
OpenPOWER on IntegriCloud