From 0e51e5e82d0c128b7779df25fac11b4c67d50425 Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Tue, 6 Dec 2016 22:49:36 +0000 Subject: [PATCH] [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 --- lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 9 +++++++++ test/CodeGen/MSP430/umulo-16.ll | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 test/CodeGen/MSP430/umulo-16.ll diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index d970ff49bba..7a04e0d033a 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -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; diff --git a/test/CodeGen/MSP430/umulo-16.ll b/test/CodeGen/MSP430/umulo-16.ll new file mode 100644 index 00000000000..bd421379147 --- /dev/null +++ b/test/CodeGen/MSP430/umulo-16.ll @@ -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 } -- 2.11.0