From 47436fa2d13149c1b45f9a401c937dbc8a310e65 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Fri, 8 Jan 2016 19:53:24 +0000 Subject: [PATCH] [DAGCombiner] don't dereference an operand that doesn't exist (PR26070) The bug was introduced with changes for x86-64 fp128: http://reviews.llvm.org/rL254653 I don't know why an x86 change is here, so I'll follow up in: http://reviews.llvm.org/D15134 Should fix: https://llvm.org/bugs/show_bug.cgi?id=26070 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@257200 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 25 +++++++++++++------------ test/CodeGen/X86/pr13577.ll | 16 ++++++++++++++++ 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 1d09123f2ea..c741982bc08 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -8795,20 +8795,21 @@ SDValue DAGCombiner::visitFSQRT(SDNode *N) { ZeroCmp, Zero, RV); } +/// copysign(x, fp_extend(y)) -> copysign(x, y) +/// copysign(x, fp_round(y)) -> copysign(x, y) static inline bool CanCombineFCOPYSIGN_EXTEND_ROUND(SDNode *N) { - // copysign(x, fp_extend(y)) -> copysign(x, y) - // copysign(x, fp_round(y)) -> copysign(x, y) - // Do not optimize out type conversion of f128 type yet. - // For some target like x86_64, configuration is changed - // to keep one f128 value in one SSE register, but - // instruction selection cannot handle FCOPYSIGN on - // SSE registers yet. SDValue N1 = N->getOperand(1); - EVT N1VT = N1->getValueType(0); - EVT N1Op0VT = N1->getOperand(0)->getValueType(0); - return (N1.getOpcode() == ISD::FP_EXTEND || - N1.getOpcode() == ISD::FP_ROUND) && - (N1VT == N1Op0VT || N1Op0VT != MVT::f128); + if ((N1.getOpcode() == ISD::FP_EXTEND || + N1.getOpcode() == ISD::FP_ROUND)) { + // Do not optimize out type conversion of f128 type yet. + // For some targets like x86_64, configuration is changed to keep one f128 + // value in one SSE register, but instruction selection cannot handle + // FCOPYSIGN on SSE registers yet. + EVT N1VT = N1->getValueType(0); + EVT N1Op0VT = N1->getOperand(0)->getValueType(0); + return (N1VT == N1Op0VT || N1Op0VT != MVT::f128); + } + return false; } SDValue DAGCombiner::visitFCOPYSIGN(SDNode *N) { diff --git a/test/CodeGen/X86/pr13577.ll b/test/CodeGen/X86/pr13577.ll index 2228fbbaa53..691d75b0e50 100644 --- a/test/CodeGen/X86/pr13577.ll +++ b/test/CodeGen/X86/pr13577.ll @@ -18,3 +18,19 @@ define x86_fp80 @foo(x86_fp80 %a) { } declare x86_fp80 @copysignl(x86_fp80, x86_fp80) nounwind readnone + +; This would crash: +; https://llvm.org/bugs/show_bug.cgi?id=26070 + +define float @pr26070() { + %c = call float @copysignf(float 1.0, float undef) readnone + ret float %c + +; CHECK-LABEL: pr26070: +; CHECK: andps +; CHECK-NEXT: orps +; CHECK-NEXT: retq +} + +declare float @copysignf(float, float) + -- 2.11.0