Currently, the InstCombineCompare is combining two add operations into a single add operation which always has a nsw flag, without checking the conditions to see if this flag should be present according to the original two add operations or not. This flag can cause future passes in the pipeline to apply incorrect optimization and generate an incorrect IR.
The following figure shows the IR before, on the right, and after, on the left, this wrong optimization and is the main motivation for this patch:
As we can see non of the add operations have the nsw falg and it was added incorrectly by InstCombine pass. A correct IR for this combined add should be %2 = add i8 %m, 2.
With the wrong IR presented in previous figure, later on the pipeline because of the misleading nsw the conditional branch instruction has changed to an unconditional branch and causing the InstCombine to delete the instructions inside a BasicBlock that contains load and store instructions. This can be seen in the following figure:
This patch will change the InstCombineCompare to emit the nsw or nuw only when these flags are allowed to be generated according to the original add operations and delete the possibility of applying wrong optimization with passes that will perform on the IR later in the pipeline.
To confirm that the current results are buggy and the results after proposed patch are the correct IR the following examples from Alive2 are attached; the same results can be seen in the case of nuw flag and nsw is just used as an example. The following link shows that the generated IR with current LLVM is a buggy IR when non of the original add operations have nsw flag.
https://alive2.llvm.org/ce/z/WGaDrm
The following link proves that the generated IR after the patch in the former case is the correct IR.
https://alive2.llvm.org/ce/z/wQ7G_e
I don't think the nuw preservation is correct if the numbers are negative. Consider this case: https://alive2.llvm.org/ce/z/r3s3bw