[CodeGen] Fix result type for SMULO/UMULO legalization

On some platforms (like MSP430) the second element of the result
structure for SMULO/UMULO may have a shorter type than the one
returned by SetCC. We need to truncate it to the right type, or
else some incorrect code may be generated later on.

This fixes issue https://github.com/rust-lang/rust/issues/37829

Patch by Vadzim Dambrouski!

Differential Revision: https://reviews.llvm.org/D27154



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@288857 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Eli Friedman 2016-12-06 22:49:36 +00:00
parent 6b92e1ac70
commit 0e51e5e82d
2 changed files with 41 additions and 0 deletions

View File

@ -3515,6 +3515,15 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
TopHalf = DAG.getSetCC(dl, getSetCCResultType(VT), TopHalf,
DAG.getConstant(0, dl, VT), ISD::SETNE);
}
// Truncate the result if SetCC returns a larger type than needed.
EVT RType = Node->getValueType(1);
if (RType.getSizeInBits() < TopHalf.getValueSizeInBits())
TopHalf = DAG.getNode(ISD::TRUNCATE, dl, RType, TopHalf);
assert(RType.getSizeInBits() == TopHalf.getValueSizeInBits() &&
"Unexpected result type for S/UMULO legalization");
Results.push_back(BottomHalf);
Results.push_back(TopHalf);
break;

View File

@ -0,0 +1,32 @@
; RUN: llc < %s -march=msp430 | FileCheck %s
target datalayout = "e-m:e-p:16:16-i32:16:32-a:16-n8:16"
target triple = "msp430"
define void @foo(i16 %arg) unnamed_addr {
entry-block:
br i1 undef, label %bb2, label %bb3
bb2: ; preds = %entry-block
unreachable
bb3: ; preds = %entry-block
%0 = call { i16, i1 } @llvm.umul.with.overflow.i16(i16 undef, i16 %arg)
; CHECK: call
%1 = extractvalue { i16, i1 } %0, 1
%2 = call i1 @llvm.expect.i1(i1 %1, i1 false)
br i1 %2, label %panic, label %bb5
bb5: ; preds = %bb3
unreachable
panic: ; preds = %bb3
unreachable
}
; Function Attrs: nounwind readnone
declare i1 @llvm.expect.i1(i1, i1) #0
; Function Attrs: nounwind readnone
declare { i16, i1 } @llvm.umul.with.overflow.i16(i16, i16) #0
attributes #0 = { nounwind readnone }