Skip to content

Commit

Permalink
DAG: correctly legalize UMULO.
Browse files Browse the repository at this point in the history
We were incorrectly sign extending into the high word (as you would for
SMULO) when legalizing UMULO in terms of a wider full multiplication.

Patch by James Duley.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@305800 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
TNorthover committed Jun 20, 2017
1 parent 46f62d5 commit f37b0db
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 11 deletions.
29 changes: 18 additions & 11 deletions lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3530,17 +3530,24 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
LC = RTLIB::MUL_I128;
assert(LC != RTLIB::UNKNOWN_LIBCALL && "Cannot expand this operation!");

// The high part is obtained by SRA'ing all but one of the bits of low
// part.
unsigned LoSize = VT.getSizeInBits();
SDValue HiLHS =
DAG.getNode(ISD::SRA, dl, VT, LHS,
DAG.getConstant(LoSize - 1, dl,
TLI.getPointerTy(DAG.getDataLayout())));
SDValue HiRHS =
DAG.getNode(ISD::SRA, dl, VT, RHS,
DAG.getConstant(LoSize - 1, dl,
TLI.getPointerTy(DAG.getDataLayout())));
SDValue HiLHS;
SDValue HiRHS;
if (isSigned) {
// The high part is obtained by SRA'ing all but one of the bits of low
// part.
unsigned LoSize = VT.getSizeInBits();
HiLHS =
DAG.getNode(ISD::SRA, dl, VT, LHS,
DAG.getConstant(LoSize - 1, dl,
TLI.getPointerTy(DAG.getDataLayout())));
HiRHS =
DAG.getNode(ISD::SRA, dl, VT, RHS,
DAG.getConstant(LoSize - 1, dl,
TLI.getPointerTy(DAG.getDataLayout())));
} else {
HiLHS = DAG.getConstant(0, dl, VT);
HiRHS = DAG.getConstant(0, dl, VT);
}

// Here we're passing the 2 arguments explicitly as 4 arguments that are
// pre-lowered to the correct types. This all depends upon WideVT not
Expand Down
16 changes: 16 additions & 0 deletions test/CodeGen/ARM/v6m-umul-with-overflow.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
; RUN: llc < %s -mtriple=thumbv6m-none-eabi | FileCheck %s

define i1 @unsigned_multiplication_did_overflow(i32, i32) {
; CHECK-LABEL: unsigned_multiplication_did_overflow:
entry-block:
%2 = tail call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %0, i32 %1)
%3 = extractvalue { i32, i1 } %2, 1
ret i1 %3

; CHECK: mov{{s?}} r2, r1
; CHECK: mov{{s?}} r1, #0
; CHECK: mov{{s?}} r3, {{#0|r1}}
; CHECK: bl __aeabi_lmul
}

declare { i32, i1 } @llvm.umul.with.overflow.i32(i32, i32)

0 comments on commit f37b0db

Please sign in to comment.