<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/100661>100661</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
IPSCCP pass wrong denormal constant optimization
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
hashemthomas1
</td>
</tr>
</table>
<pre>
Hi,
I work on a target that supports denormal-fp-math=preserve-sign,preserve-sign mode and I've encountered the following bug:
https://godbolt.org/z/Tj78Y63KM
In the link I'm using x86 top of trunk compiler with the addition of the command line flag:
-fdenormal-fp-math=preserve-sign,preserve-sign
As you can see, a wrong constant propagation happens as one of the operands is a denormal.
The output of the optimized function is a denormal when it's supposed to be 0.0f.
After debugging, I found out that the bug happens in IPSCCP pass when it tries to simplify a binary operation.
More specifically, in (/llvm-project/llvm/lib/Transforms/Utils/SCCPSolver.cpp):
```
void SCCPInstVisitor::visitBinaryOperator(Instruction &I)
```
The following line:
```
Value *R = simplifyBinOp(I.getOpcode(), V1, V2, SimplifyQuery(DL));
```
Initializes a SimplifyQuery instance without a context, which results in a chain of function calls reaching the function
(/llvm-project/llvm/lib/Analysis/InstructionSimplify.cpp):
```
static Constant *foldOrCommuteConstant(Instruction::BinaryOps Opcode,
Value *&Op0, Value *&Op1,
const SimplifyQuery &Q)
```
In case a context is **not** given, the function:
```
ConstantFoldBinaryOpOperands(Opcode, CLHS, CRHS, Q.DL);
```
and doesn't flush inputs to zero when needed.
Otherwise, if a context **is** given the function:
```
ConstantFoldFPInstOperands(Opcode, CLHS, CRHS, Q.DL, Q.CxtI);
```
is called instead, performing a correct constant fold that flushes inputs to zero.
Therefore, the solution would be to pass the context to the SimplifyQuery initialization in (/llvm-project/llvm/lib/Transforms/Utils/SCCPSolver.cpp):
```
Value *R = simplifyBinOp(I.getOpcode(), V1, V2, SimplifyQuery(DL, &I));
```
Note that even though EarlyCSE also calls the function SimplifyInstruction,
we don't encounter this bug because the SimplifyQuery instance is initialized with context.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJy8Vl-P2r4S_TTmZbQoGMLCAw8sW1R020vb7a10H514krh17Mh_oOynvxonwLLqturD_UmreE1sz8w5Z04svFe1QVyx_IHljyMRQ2PdqhG-wTY0thV-MiqsPK3eK8Y3LHtk2bp_7uBo3Q-wBgQE4WoMEBoRwMeusy54kGisa4W-q7q7VoSGTR87hx7dAe8oKuObmzm0ViIII2HH-P0BAU1pownoUEJoECqrtT0qU0MRazYd8mhC6DzN-JbxbW1lYXUYW1czvn1mfPv1-_3iv_Ppvz7eJG_SiVqZHylaC9HTwT8Xcwi2A1tBcNH8gNK2ndLo4KhCk_YIKVVQ1qQ1DdKKlpLWyiBUWlBm0Ee5q_4Wg5c5rj2cbIRSGPCIjG9AwNFZU0NpjQ_CBOic7UQtUjqN6Do0HoQHa_Ccne3QCSM9KA_iQsm4j_CVFsTQxXBdHlSrnlFCFU2Zzr3ZCMcGDajA-L3vmfZEjoUCIRtn1fimgCqgA4lFrGtlaqpgB5WNRlLUXi0UtIj1JXtlYPfpabP5BJ3w_hwOglPoKY5XbadVdQIBhTLCnfoKKdMh9kfrEHyHpapUKbQ-UVxlgPEF41utD-1d5-x3LMMwpUEVpBQnjK-saz3j2_8EpWmkXJ6sPqAbl13H-PIiPDbPhr80PVglgVbvjA_flFfBOlo7XR9o8pCy3adkrWN8Qctc7DFmfL6jo3917pWqq_5Ja2_l8U3oiMD4-guw6eMFsAdl9h2FHdcY9l1pJSZElgTPt0l6cno-DRs-R3QnxhePH9KiJZs-_DLezqighFbPSEK52Q0q6bRESO1DpAsSb8CfgUIdG1U24NBHHRL1AspGqNRaF_0Rhx4cirKh0pMRDO-GfP5I7NoIffKK6HyB-jnVP_DqgwiqhM255xhfV1bLvdvYto0Bzy9uKe2ZP5Pu4Yz4YKFwYYnx-b7LEvw3P02ua1O7v0KW8fnn3ytmR9B5vCJOnZxOXxsb-n-gVgckE7qF9Q0kzpVurZbnyvaDvzC-uJQImw_vn9L4pR8_j3sRvaEgck9p0RvG7wNUOvoGlOliSB3_jM72PmAQJcobi9mHBt1R-RRWVS-K7Qskzq-F_nWV29TMf1EjjZufYfebapVPkkaZugOFpF0dOjIeEjiV4ByW4WrzpLfeLhM46F_BM37lFA4r6_BMq7c6pk462qglOXWwvbv2n68er2DT9HX_Dr3df2L-ARf9f7jX5uKvb7PSP_9tA_ZAYy8XG-sG3gmnT5undyC0t4MfvVTSJejL_qeo6cwjgrS9tC8XGgiN8um7V2AposdfYj94p_JXHlD2F5GBtYH4kVxN5XK6FCNcTe75ZDnL8-li1Kyy2bTi82xSosixmJVZUS54zvOsyPPpcjoZqRXP-Cy75znnEz5ZjPlCYL7Mq8lMLGd5NmGzDFuh9Jg4plvVSHkfcTXJsvl8MtKiQO3T7ZFzg0dIbxnndJl0q6STItaezTKtfPDXY4IKGlc33_p0t7ncNC7qH-4kSYKj6PTq1Y1PhSYW49K2L5R4q8-UFMlwyPqw4v8LAAD__xWWgzk">