From: Owen Anderson Date: Fri, 26 Jul 2013 21:40:29 +0000 (+0000) Subject: When InstCombine tries to fold away (fsub x, (fneg y)) into (fadd x, y), it is X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=commitdiff_plain;h=0c326f07ca713fa00d0dcba8ec9b61e91298f690 When InstCombine tries to fold away (fsub x, (fneg y)) into (fadd x, y), it is 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 --- diff --git a/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/lib/Transforms/InstCombine/InstCombineAddSub.cpp index 0aa301bc7a8..8d4677b0ec6 100644 --- a/lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ b/lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -1528,9 +1528,21 @@ Instruction *InstCombiner::visitFSub(BinaryOperator &I) { 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 (FPTruncInst *FPTI = dyn_cast(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(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)) diff --git a/test/Transforms/InstCombine/fneg-ext.ll b/test/Transforms/InstCombine/fneg-ext.ll new file mode 100644 index 00000000000..49ad2325261 --- /dev/null +++ b/test/Transforms/InstCombine/fneg-ext.ll @@ -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 +}