From d530427b4adf925c2701229587e1884484ed3798 Mon Sep 17 00:00:00 2001 From: Ranjeet Singh Date: Wed, 26 Apr 2017 13:41:43 +0000 Subject: [PATCH] Fix signed multiplication with overflow fallback. For targets that don't have ISD::MULHS or ISD::SMUL_LOHI for the type and the double width type is illegal, then the two operands are sign extended to twice their size then multiplied to check for overflow. The extended upper halves were mismatched causing an incorrect result. This fixes the mismatch. A test was added for ARM V6-M where the bug was detected. Patch by James Duley. Differential Revision: https://reviews.llvm.org/D31807 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@301404 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 4 ++-- test/CodeGen/ARM/v6m-smul-with-overflow.ll | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 test/CodeGen/ARM/v6m-smul-with-overflow.ll diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 3bae3bf9ab7..fdebb8bd00d 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -3497,11 +3497,11 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) { // part. unsigned LoSize = VT.getSizeInBits(); SDValue HiLHS = - DAG.getNode(ISD::SRA, dl, VT, RHS, + DAG.getNode(ISD::SRA, dl, VT, LHS, DAG.getConstant(LoSize - 1, dl, TLI.getPointerTy(DAG.getDataLayout()))); SDValue HiRHS = - DAG.getNode(ISD::SRA, dl, VT, LHS, + DAG.getNode(ISD::SRA, dl, VT, RHS, DAG.getConstant(LoSize - 1, dl, TLI.getPointerTy(DAG.getDataLayout()))); diff --git a/test/CodeGen/ARM/v6m-smul-with-overflow.ll b/test/CodeGen/ARM/v6m-smul-with-overflow.ll new file mode 100644 index 00000000000..6e8a7041de2 --- /dev/null +++ b/test/CodeGen/ARM/v6m-smul-with-overflow.ll @@ -0,0 +1,16 @@ +; RUN: llc < %s -mtriple=thumbv6m-none-eabi | FileCheck %s + +define i1 @signed_multiplication_did_overflow(i32, i32) { +; CHECK-LABEL: signed_multiplication_did_overflow: +entry-block: + %2 = tail call { i32, i1 } @llvm.smul.with.overflow.i32(i32 %0, i32 %1) + %3 = extractvalue { i32, i1 } %2, 1 + ret i1 %3 + +; CHECK: mov r2, r1 +; CHECK: asrs r1, r0, #31 +; CHECK: asrs r3, r2, #31 +; CHECK: bl __aeabi_lmul +} + +declare { i32, i1 } @llvm.smul.with.overflow.i32(i32, i32)