<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/60389>60389</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            _FORTIFY_SOURCE causes more aggressive optimisations than unfortified
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            clang:codegen
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          hvdijk
      </td>
    </tr>
</table>

<pre>
    Please consider the following example, heavily reduced from real code.

```c++
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
  void *p;
  size_t n;
  if (getenv("TEST")) {
    p = &n;
    n = sizeof n;
 puts("Hello");
  } else {
    p = nullptr;
    n = 0;
  }
 memset(p, 0, n);
}
```
This code has undefined behaviour if `TEST` is not set, despite the user's expectation for `memset(0, 0, 0)` to have no effect. This UB permits a compiler to assume that the `getenv` always returns non-NULL and emit an unconditional call to `puts`. In Clang, this is done when `_FORTIFY_SOURCE` is used. When `_FORTIFY_SOURCE` is *not* used, the code has the "expected" effect.

That is:

```sh
$ clang++ test.cc -O3 -U_FORTIFY_SOURCE && ./a.out
$ clang++ test.cc -O3 -D_FORTIFY_SOURCE && ./a.out
Hello
```

If this optimisation is worthwhile, it should also be performed in the `-U_FORTIFY_SOURCE` case. If this optimisation is not worthwhile, it should not be performed in the `-D_FORTIFY_SOURCE` case. But the current behaviour means that `-D_FORTIFY_SOURCE` is unsafe to add. It means that code that works fine and does not access any memory out of bounds suddenly starts breaking when `-D_FORTIFY_SOURCE` is added.

This appears to happen because `memset` function call is translated to the [`llvm.memset.*`](https://llvm.org/docs/LangRef.html#llvm-memset-intrinsics), which is documented as a nop if the length is zero even if the pointer is null. When `-D_FORTIFY_SOURCE` is used, more complicated IR is generated that means SimplifyCFG is able to infer that the `else` block results in UB, therefore the condition may be assumed to be true.

On the LLVM side, I think everything as working as expected. The IR generated for the `-U_FORTIFY_SOURCE` cannot be optimised, so it isn't. The IR generated for `-D_FORTIFY_SOURCE` can be, and is.

On the Clang side, I think the fact that more aggressively optimisable LLVM IR is generated when extra safety checks are requested is incredibly unfortunate, unfortunate enough to ask if there is any way to change that.

Seen with Clang 15.0.6, reproduced on [godbolt.org](https://godbolt.org/#z:OYLghAFBqd5QCxAYwPYBMCmBRdBLAF1QCcAaPECAMzwBtMA7AQwFtMQByARg9KtQYEAysib0QXACx8BBAKoBnTAAUAHpwAMvAFYTStJg1DIApACYAQuYukl9ZATwDKjdAGFUtAK4sGe1wAyeAyYAHI%2BAEaYxHoADqgKhE4MHt6%2BcQlJAkEh4SxRMVy2mPaOAkIETMQEqT5%2BRXaYDskVVQQ5YZHRegqV1bXpDX3twZ353VwAlLaoXsTI7BzmAMzByN5YANQmy269%2BKgAdAg72CYaAIIraxuY27v7tHgRx6fnV2arDOteWzt7BGIwWAr2WZ0u72CBE2LCYwQgk22AHYrJdNpsAG6oPDoTYAKliO1RF3RiQAXpgAPrQhhE97ovBUTbQTAERgYiDmMwAFWwQm5XMmiJMKPp6M2sXuABFtmYAGy05bE8WbBjSzbkzCoJmK5Xi2JeAgKTlmMwACRKtFQgrpaORMpKSmRevRkp2MoYXlotFigNtJPFavdmw0/vRIqlYrYLCUBAgsVIIcTDEm/ojHGmtE4AFZeH4OFpSKhOG5rNYNbN5ncVjxSARNBnpgBrEDZjT6TiSPMNoucXgKEDt%2BsFjOkOCwGBQScQJBoFixOjRciUOcL%2BgxdaGYBcZYaIpYDF4BYANTwmAA7gB5WKMTi1mi0NnEAcQCI9iLBKoATzvvA/zGIL9LwibQmmHWs5zYQRLwYWgfxHUgsFhIxxAQ/BiDAvAMUwAcEMwVQmkNRZayhEoeyeCJiG/DwsB7QE8BYX9pioAxgAUU8L2vW9uF4fhBBEMR2CkGRBEUFR1AQ3RpAMIwUDLSx9GeAdIGmVBfWSXCAFpL2WTZNLkSkADFLwAJW5ABJQyAE1KSES85BMtxsH7EpMOcCBXAGepSECUY8gKDJEjKFJPDqQKsgYDp/ImYpShaYYvJ6VzmnKYYoq6QpbAS0LBiytp0vGQppgUSsFgkTMc27BDiw4TZVAADjlTS5UkTZNyMTYd0ODRDi4ZlcEIEhZWWKZeGHLQhVIBBMCYLAYgRUgWzbDsOC7UhGNNQ5TW2nbduzUh80LGr%2B0HOsG2mcdEBQVB50XMgKAgVc7pQGTt13fdMEPE8zyvG983vOgnxfN8EP/b9f1IMHAOA0CHAhyDGAIGC4J7JCt1Qwt0Mw7DcMLfDCLZCHSKzBCKKowCaMWQt6MYnjmNY9ifq4/7eNkATxGEvj5CUNQe10IpXrkyxrEUiJlIWtTgq0nS9KlIzTIs6zbPsxznNity/A8hh3By7zfNyDLwuCxKiniILkgKgKGmS4LWn6XWkri1L8r8w2hjaE28uqS2JmK0qhIqjhcwOnsarqxrmta9rgE65Zut6/r8CIYhhtGs6R0m6bZu6BalvbEm1sO3hjtsU7xsbFazF4DakW6%2Brlgbxum4buUQ%2Bqvt04msdp2nWcbrXJcHqe9cXq3KQNHbA8j0wDjfu4gHH2iYH30/QCIahoCQLA%2BGbqgpHYPgzHMGQ4AMd4LHmhxnt8eQIiicEMjSeecmv0puigVpnh6aYNjZ%2BZiGubsyEtILmYleaSRAGYfQW4hZWAUhRcWql1ICGlrpfS8szKWRsnZByTkXJO01p5B2RR9ZjCtqQM2EVPaUOCj7TKjQUoMDtjUYh6tGHMLoT0bKaRvK9BdgbQq5UZhzDKlMFawci69lqg1JqLU2qvU6pIeOGhE6DRTjWSYY1zrTCznNSgzZWz507NXEAyxa5tgnpYqxE8iiSJLgOIc51u7wBnNdW665lyPX7s9aO49J6fWnn/P6ADAZL0oCDQsG916r03rDcCvAEbQQPqjY%2B6MqbnzwBhS%2BOFr4EVvoTHi5AH4k0LGTaiGB0l1g/kxPgDMgnz1ZvxUQHMQGyDARJQsuh9qC1MMLeBSl4BIKlpwbSaC5bGUwUrHBqt8EaxcNrT2pDoqZRockahmRaGu0EdbAhzDPYMNtmlLZ5C%2BH2x4Vw/hZDfbCKrEIkmEjQ6cHDrIqOCipDKNUcnVOmjO4V10TnAxy0C5VSOh3BxvzJokyrutUxcpDiSGzPXZuTdpB2I7uXC6PcXF93cYPFc3iR7R2pMQLwDAmyIQCd9TiwTCkPiBuEleAF4K1g3jDbehTEn7xRmhVJKFKkX0cFfPCeS76FOJuRZ%2B5TaIIRpjUliP9GbUoaSJYQzTgEqvaXzUx0DZK9LgTYBBgyizIIYKgvSBkJmK2wSrPBbDgrzJ1uckh2tOGmw2Ws1hqzsjHJigc%2BKHtWF%2Budt7H19DuFhXdiGgRVs/YiIDuIkFxcnkyMjvIrczJASkqbIiCAA0vkaK0RnQFRjVomOWHChFSLkWN1bmijgJ1HEZ2cbAHFA97r4txRuV6xKs0Uq%2BjPJmNKF70tfIy8GhTWVbzhhy3eiNkaH3Pry0%2B/LMnYxycKgmxFeDiqfpRKVlTZV01qQq%2BpLMVVAIkK00SPMOk6BAK3Hp8kDUDJUsa4ZHBRmywwVa5WuC1ZBsIQs1hSy3YUPdQIdZ5tvXRt9Tbf1ZyI12vgyMGDYaA1Oq9ihq5RUbmiMDg89u0iI5yOjhmklZKc15qGgWiFOiZp6NzoYlahdHn1tLo2iagdoWMXLfCxF1am61tY4Wzji0mMk2WImqRImK5QqkyXDF0xsLPmSCASQQA) on plain x86-64 LP64. Started with Clang 14 and still persists in Clang trunk.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJyMWFmzorzW_jX0DdW7AAX1oi_CKAIqgwPenAoQITJKgoi__itw99v77a_71KnaxcZkZY3Ps5IACcFphdAPRpQZUf0GO5rV7Y_skeBb_i2qk-HHvkCQIDauK4IT1LI0Q-y1Loq6x1XKoicsmwIxgsJmCD5wMbAtSroYJey1rUu2RbBg4zpBHwynMhz4fErc-y9mBHn8e48KM1zFRZcglpkphCa4_siYmfaX2QJH_2W6xVX6dXp64oqyJcQVIywZYcUyi0_LLPuoccIyAmiY2T9jBL_QfyhbfRnCV5YRlimiqHpMSoRA8wNGEBhh9ZtGlm1YZqayjCB91cCy1TQ8Kq-vX5U3HSVvnWtUFPWn0l8rmYXKooKgPxmpuqJoaPsHO9y_NXy-lqgkiDLCshkrx42P6qu1fyT_qdT7Z5BhMpWTzSBhuypBV1yhhI1QBh-47topQxI3ZUXiWEzYqqbsZEthE0QaTNEEoY6glhEWhEXPBsUUUlxX7LVux9X_eMf94x03eidxLK3ZDD4QW9Usul5RTD_YyaeDzDaoLTElLGTjumxwMWK1ZiEhXTmahHSyy0jcZ_kkjoVFDwfCtoh2bTW6Wn3fHmybhVXCohJTFlZsV8V1leDRvxHKsChGtYzETfWSuA_WrFilgFU6-klHZzBhk7pCbJ-hapT8j77zAlMP_-PvDp6ifSamIyj5YE__VYYRQFVTRgCT9NsA-lWAKSBBeKdwnBd-ZuUr6oMxdkyYGfgjB0n2k0FzNn7HMXKSpYjQjzhmv-9m7PfDb_6NsGYEif1gBB1-1B39H3So_5uON_r_hL7307y-s1w3FJeYvJGDCdvXLc36DL-7EaYsyequSFhYkJqN0IiPa92WKGFx9RMK_y-uMe8xJOiD_ZuZEc9_MzXO_c3S79H_siR3b2jGXduiin4hU4lgRd7Y_ZuKEUgVgVc0gT1JPliTfl03YWV66-s2J-zI1wnfSY3ewcA4RoSwsBrGtlC3A1t3lK2vbFR3VUJY0iUJqoqBJRS2lLBRi2A-9v6f8P6bXzBJUPIbEsfhpkGwJW8qNw2q2AjFsCPoC_Uljr12VTzlfKIcJixtYUUKSFEyLp3SKsqMxBXFo_x4r_tghAkzosoIy4zSZgK9oDOCPknVbcoIelLHhBF0G1aph64fGS0LRpiNAt_far7jatw_CB7lVmOJ-wzH2ZvXcVeianQCjq2mqpux5Y3eFKhK6ST0Qm3Nogeqfk41Na4oaif4dEXxi_V_Lekn28u6RVM7K3A8RW5643SKKtS-MzFW9l1uH49i10HRjSn7UTFhAlfXadf-1f_GTWS0ExV1nLMtIl1ByQjVg_zZYVp0HQ2_e81n82NLOIzgfjfUqQYRYmnb_Xtr370Rb9tHhx0PDKNGc2RSlY8paYfxNR2TN-Lx8_VnAxubORpj_BXguCX8d7JWn6z7JOo7caQeaYlJxQgL-he1f2flCMlRy8gTTP4U39Tw_1-A09kIxvSzLGMOYZq2iBD8QMXwTy8ZSzNl6PdyTpRCT9pCduQ0Hdg4Q3FOWNgitkX3DpFRbNxjqrhFCY6Kge2qa93SroJ0cubLTxZVdZdm730w_0RjiyZ4VAPbw2GcijNYpe8m8a9QfYQqtsc0-4yWFz-4D2k00aKmrd-nvLoaaZjWSVQXdCLYH8j3dXocmL2YGdiFdpoBXb4noqs8QdjvQ9lRStlLZBvovKvEAO41BTivXqYOWAC316njygPw0pVF3VADA8ER556B8lzKMrBquQoAOIB10wPnAfQw8Okm5VUTNEAJgduFXV6sLiDoVeuWAEM_UGDNiYH4HgwIDCFYm4wgCjLQYPhc10C9p1amzZ01labx2C02INeyuf_0nOMglHu4A7mpBY6r3QNxkvHOMFRJfjy6rhhe1h5K70c-OjfqeUb7y0ycHXtQ2LA-k8BcyK8SOC952Ioh2LrlIEirSYmVggSkC0EJITDNFj67UFg8FnSdek_pWh0F2Ko7ik4vupANsz-BVjhduG4hKLIm2ErYu2kuCGAdtptk2xBgSPVerYMQWAXe8Z4-87ALzk0K9q2bZdpqUT_kQxC5AdC8NMRq6fRAP_VuKZ6dEm8ca99IjkDOHZB1WobAGDgx0panSL75ryh_KfWmtMQzFjYIpFZQjOsVz6K6m7YN3HlOY_mlhx5e3ghOHZ6Lmuo43dLNXoePpOw5RtAfnnkvwja0lYMMUnI0zThQtZIR9Pq2NkqqzYF-Qev5Tm98K9sZYrsNt9FWrOLj7ekDbytXTSq3mnq5BVKA_b2zrbv4nFqaSqekEv22y3dKb8iuH7sbudbxc3fzYnzYxfYkkT4TaIRyfAmh2YSqPpdDsA36EoBFKosnywkwX2JuW2kgdhVzhW3ZqkHwejxGoL8M017ZPY7cslyfiPgKXc_uw1N6fa4PKdEz8_kELiPoMlbBAziHHsSa0x_dMt96FzhkWo0GpGywwQi62hN54WpLOTyvGlyDZwoOh6UtPE6rTp9fM1nWHE9QcsOTtYPu8cCdeQ1wzP6g2v5zZSCQmEZ5lK8n_6wAvbGFU3DZ2rmfA1W3e7A5iUDeuAPQeMvX_KUoO_RJ1gutcXaxIp-BgRpfUw7hMrXUjXaz9M1evbsWSUO1YQTdLMPGz2AYPjbS8VVWVhjWd8ltIuBztowH2nAPw22a9OATPc0DJxYWsor7eXA5AqDeisAXD3lw2Q5OECbcTvVUPL8UsWZq2eV0si7IWNtudjRl2VFCG4Spd0hPr0glO2VxyIzt1hWDk1BFSfc6ZEvONtqphNx6RwyhjBNNdo-yyJ2d1ALpMV40rhFQfnZNHG2vLV_Dw1gtZ49dWj2v26W2ZwQ9Wl1501mDHeCUNcgG1QCmocw3i41CebennNMv1Nixr6piX5S1b71kxbLqXoHOyaWSE1a3chuu8PU-ZwR9gbY5CJ6G9riJymHrIp4zm3ObD89WO-BNYZ5okN65yl9ZhfkKTCK9oj15vqotpgMj6GCZZTN5WLyu20G1-055WrjCpp2nVmoZpT-3T5V0PuUt5u1lu-yF7AY1YdndfWFTWtw9M--3LO53FYHt_dmWFK7aVJPESzc2M71dKmaYZdQgkseVUnTpJBkWj0grebKbZTdKDosniXT40ucqzE_vBtgWafTsynnUHdxp4P6g3LwkSSNUpzhqz5t4fUer-HyfWe52HYHljevV27Wbp-u1gMP1bGS6q5gwqxXXBpMOI7qnzTrcp6-1Y7hz4CRze11mz4oukWtiHGvOzUcoLh9c0-H02FSZBMPt7TKtvmCji8igUdMuwwJB3wNGeHVP8-xyAofMi0_3gjcVo2ibq78kL-vkkeoiD0F-3uw4vhFlwfNWl5tC764jaMc9POyU2yKwbu6hdlR6O4SZRI21Y9cBF1nQe1grOUkj9y4eLtlLtQpHh32MpVVxT_nN3T4I98dBaky0MzJNUr3gdvLDkH-1gfKqtn76upxeIrfYnjUwPKFI06oJ709tibG_sdOdGYt8t-jlapucJEkshv15QVZwN19tpOupqhhB30tABRebqxXVJcaKl1pu1qqx8gBa5Lr7-y2cMiM596h69XLmTz93ejvXjo86WGMRrOc5ZxsBxIbMFfy4K-fPfao6afXiL4_nwV07rjGowNu4pMtWd4V3HBvJfjGXTato-siHihgZh_7QruU7XWrwGW_bQGjU-n7x6jiHWelBo-O0JALZS92HzpaWhX0RlcmZtfCcH3tG0LOLeo0Uq9XMvNRurhSv1da87xTcqNb2EFfHXXnbzY88F1TgOXCKePR32Ux-Pl6bOh_ajh6ecaNi33jtz5cuSBpZMBfdWZH28VlfzeJwr8cz7C08oXFcu1dBOZiukqwC3AdKvsdypxUI6HOLT2c3NUJZoFWLp1dmx42lW_mZi_XrXkH-QtJ3m857Y04MoGl6ze1Q4P3KiA419Deh-wpS7f6A59fhyakXa2WnQSjL6YBfphla6cOX801pCb3f7uVITdvXhu_iPBPozih74UT47P4it_UGp_H7ELCmJ3166xK6WPMrtdOzc4KN1DuOF5gQm2pn5vozrvLBuT3MNn5tgJ_fIxMrAHCPHFqcV7m6dzvW5e60VjLdt_PTlo9KfEs3_Fq7CHEE1jpYLdo5fXrdUXpahDvcJ6u3_abcWvqCo1dzWBpZcDpGrywbZghvc7ie7duBmwTHy5RThc8httLyqSMV36-NZx2L4HLk-Lv7VtfYzvEIzNziOH_v7HJJBtZs3Sxz9aBuDgTOL2vZK4e-P0Lx1Cn8RSamS_jMH2bhYZ-4ZnIR6ePs0VUQXfnLYPLCIx0cQw0h4Hf3Fc7uoneISuyo6XLVcdgUh90tK_PiYsW8eDfSE9Z3-NJI21cdFjBL1hVP7VrAME3qk3O2r8pT52Ep8TScn143zJVOLpzM8u6ZpSW693w4qzr3JPa-9BXguy5ghNV4Am4KiCv2uZS-S3PW3kvzD9YfL8vjif7L-Xk-XSgIxUXBNqglmLzvXe9p2nZV_vEt-TFLVrMV_IZ-8NJC5Ln5aj7_lv1YzXi0QAlCi3jBcfEiQnEkcqt4fo1QxEfcN_xD4IQZx884fimK8_kHhJIoCvAqJDGcx8mMmXOohLj4-HkX_oYJ6dAPiZstV98KGKGCTB-CBeH9DWcG4jpBKaoYQWBE9Vv7Y7okR11KmDlXjO7_0kUxLdCP3z_xTBd78vtV6F8fVaYPFdXntQVfMUq-dW3x47cbBKZZF33Edfl5l__8971p6xuKKSPoUzAjL6Z4_i8AAP__XzJi4Q">