[llvm] [Reland][InstCombine] Fix FMF propagation in `foldSelectIntoOp` (PR #114499)

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 31 19:49:39 PDT 2024


================
@@ -564,6 +561,12 @@ Instruction *InstCombinerImpl::foldSelectIntoOp(SelectInst &SI, Value *TrueVal,
     BinaryOperator *BO =
         BinaryOperator::Create(TVI->getOpcode(), FalseVal, NewSel);
     BO->copyIRFlags(TVI);
+    if (isa<FPMathOperator>(&SI)) {
+      // Merge poison generating flags from the select
+      BO->setHasNoNaNs(BO->hasNoNaNs() && FMF.noNaNs());
+      BO->setHasNoInfs(BO->hasNoInfs() && FMF.noInfs());
+      BO->setHasNoSignedZeros(BO->hasNoSignedZeros() && FMF.noSignedZeros());
----------------
dtcxzyw wrote:

> No signed zeros aren't poison generating.

Yeah. It is a value-mismatch issue.
```
----------------------------------------
define half @src1(i1 %cond, half %x, half %y) {
#0:
  %add = fadd nnan ninf nsz half %x, %y
  %sel = select nnan i1 %cond, half %add, half %x
  ret half %sel
}
=>
define half @tgt1(i1 %cond, half %x, half %y) {
#0:
  %add = select nnan i1 %cond, half %y, half 0x8000
  %sel = fadd nnan nsz half %x, %add
  ret half %sel
}
Transformation doesn't verify!

ERROR: Value mismatch

Example:
i1 %cond = #x0 (0)
half %x = #x0000 (+0.0)
half %y = #x0000 (+0.0)

Source:
half %add = #x8000 (-0.0)
half %sel = #x0000 (+0.0)

Target:
half %add = #x8000 (-0.0)
half %sel = #x8000 (-0.0)
Source value: #x0000 (+0.0)
Target value: #x8000 (-0.0)
```

> But I'm not sure why it's correct to preserve reassoc

Proof:
```
select Cond, X, (X reassoc op Y) ->
select Cond, (X op Id), (X reassoc op Y) ->
select Cond, (X reassoc op Id), (X reassoc op Y) ->
X reassoc (select Cond, Id, Y)
```

We don't set `reassoc` for select/phi if they are constructed by SROA + SimplifyCFG.


https://github.com/llvm/llvm-project/pull/114499


More information about the llvm-commits mailing list