summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Friedman <efriedma@codeaurora.org>2016-12-06 22:49:36 +0000
committerEli Friedman <efriedma@codeaurora.org>2016-12-06 22:49:36 +0000
commit0a76e3241f05a996a2a507a5c32476326d2b3355 (patch)
treefba0c568c87092661013b23bb3dd9f7983105316
parentac066f354a9c5cd8f00765e81f3e0db56983c29e (diff)
downloadbcm5719-llvm-0a76e3241f05a996a2a507a5c32476326d2b3355.tar.gz
bcm5719-llvm-0a76e3241f05a996a2a507a5c32476326d2b3355.zip
[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 llvm-svn: 288857
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp9
-rw-r--r--llvm/test/CodeGen/MSP430/umulo-16.ll32
2 files changed, 41 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index d970ff49bba..7a04e0d033a 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/llvm/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/llvm/test/CodeGen/MSP430/umulo-16.ll b/llvm/test/CodeGen/MSP430/umulo-16.ll
new file mode 100644
index 00000000000..bd421379147
--- /dev/null
+++ b/llvm/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 }
OpenPOWER on IntegriCloud