When InstCombine tries to fold away (fsub x, (fneg y)) into (fadd x, y), it is
authorOwen Anderson <resistor@mac.com>
Fri, 26 Jul 2013 21:40:29 +0000 (21:40 +0000)
committerOwen Anderson <resistor@mac.com>
Fri, 26 Jul 2013 21:40:29 +0000 (21:40 +0000)
also worthwhile for it to look through FP extensions and truncations, whose
application commutes with fneg.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@187249 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/InstCombine/InstCombineAddSub.cpp
test/Transforms/InstCombine/fneg-ext.ll [new file with mode: 0644]

index 0aa301bc7a818af11ad1e155c3caa2f41c6776c0..8d4677b0ec62a03e912075473f159a14ef9c49f3 100644 (file)
@@ -1528,9 +1528,21 @@ Instruction *InstCombiner::visitFSub(BinaryOperator &I) {
       if (Instruction *NV = FoldOpIntoSelect(I, SI))
         return NV;
 
       if (Instruction *NV = FoldOpIntoSelect(I, SI))
         return NV;
 
-  // If this is a 'B = x-(-A)', change to B = x+A...
+  // If this is a 'B = x-(-A)', change to B = x+A, potentially looking
+  // through FP extensions/truncations along the way.
   if (Value *V = dyn_castFNegVal(Op1))
     return BinaryOperator::CreateFAdd(Op0, V);
   if (Value *V = dyn_castFNegVal(Op1))
     return BinaryOperator::CreateFAdd(Op0, V);
+  if (FPTruncInst *FPTI = dyn_cast<FPTruncInst>(Op1)) {
+    if (Value *V = dyn_castFNegVal(FPTI->getOperand(0))) {
+      Value *NewTrunc = Builder->CreateFPTrunc(V, I.getType());
+      return BinaryOperator::CreateFAdd(Op0, NewTrunc);
+    }
+  } else if (FPExtInst *FPEI = dyn_cast<FPExtInst>(Op1)) {
+    if (Value *V = dyn_castFNegVal(FPEI->getOperand(0))) {
+      Value *NewTrunc = Builder->CreateFPExt(V, I.getType());
+      return BinaryOperator::CreateFAdd(Op0, NewTrunc);
+    }
+  }
 
   if (I.hasUnsafeAlgebra()) {
     if (Value *V = FAddCombine(Builder).simplify(&I))
 
   if (I.hasUnsafeAlgebra()) {
     if (Value *V = FAddCombine(Builder).simplify(&I))
diff --git a/test/Transforms/InstCombine/fneg-ext.ll b/test/Transforms/InstCombine/fneg-ext.ll
new file mode 100644 (file)
index 0000000..49ad232
--- /dev/null
@@ -0,0 +1,12 @@
+; RUN: opt -instcombine -S < %s | FileCheck %s
+
+; CHECK: test1
+define double @test1(float %a, double %b) nounwind readnone ssp uwtable {
+; CHECK-NOT: fsub
+; CHECK: fpext
+; CHECK: fadd
+  %1 = fsub float -0.000000e+00, %a
+  %2 = fpext float %1 to double
+  %3 = fsub double %b, %2
+  ret double %3
+}