[llvm] r335093 - [SelectionDAG] Don't crash on inline assembly errors when the inline assembly return type is a struct.

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 19 21:32:05 PDT 2018


Author: ctopper
Date: Tue Jun 19 21:32:05 2018
New Revision: 335093

URL: http://llvm.org/viewvc/llvm-project?rev=335093&view=rev
Log:
[SelectionDAG] Don't crash on inline assembly errors when the inline assembly return type is a struct.

Summary:
If we get an error building the SelectionDAG for inline assembly we try to continue and still build the DAG.

But if the return type for the inline assembly is a struct we end up crashing because we try to create an UNDEF node with a struct type which isn't valid.

Instead we need to create an UNDEF for each element of the struct and join them with merge_values.

This patch relies on single operand merge_values being handled gracefully by getMergeValues. If the return type is void there will be no VTs returned by ComputeValueVTs and now we just return instead of calling setValue. Hopefully that's ok, I assumed nothing would need to look up the mapped value for void node.

Fixes PR37359

Reviewers: rengolin, rovka, echristo, efriedma, bogner

Reviewed By: efriedma

Subscribers: craig.topper, llvm-commits

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

Added:
    llvm/trunk/test/CodeGen/X86/pr37359.ll
Modified:
    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=335093&r1=335092&r2=335093&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Tue Jun 19 21:32:05 2018
@@ -7741,8 +7741,17 @@ void SelectionDAGBuilder::emitInlineAsmE
 
   // Make sure we leave the DAG in a valid state
   const TargetLowering &TLI = DAG.getTargetLoweringInfo();
-  auto VT = TLI.getValueType(DAG.getDataLayout(), CS.getType());
-  setValue(CS.getInstruction(), DAG.getUNDEF(VT));
+  SmallVector<EVT, 1> ValueVTs;
+  ComputeValueVTs(TLI, DAG.getDataLayout(), CS->getType(), ValueVTs);
+
+  if (ValueVTs.empty())
+    return;
+
+  SmallVector<SDValue, 1> Ops;
+  for (unsigned i = 0, e = ValueVTs.size(); i != e; ++i)
+    Ops.push_back(DAG.getUNDEF(ValueVTs[i]));
+
+  setValue(CS.getInstruction(), DAG.getMergeValues(Ops, getCurSDLoc()));
 }
 
 void SelectionDAGBuilder::visitVAStart(const CallInst &I) {

Added: llvm/trunk/test/CodeGen/X86/pr37359.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/pr37359.ll?rev=335093&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/pr37359.ll (added)
+++ llvm/trunk/test/CodeGen/X86/pr37359.ll Tue Jun 19 21:32:05 2018
@@ -0,0 +1,17 @@
+; RUN: not llc -o /dev/null %s 2>&1 | FileCheck %s
+target triple = "x86_64--"
+
+ at a = global i32 0, align 4
+
+; CHECK: error: couldn't allocate input reg for constraint 'x'
+define i32 @main() {
+entry:
+  %0 = load i32, i32* @a, align 4
+  %cmp = icmp ne i32 %0, 0
+  %1 = call { i32, i32 } asm "", "={ax},={dx},x,~{dirflag},~{fpsr},~{flags}"(i1 %cmp)
+  %asmresult = extractvalue { i32, i32 } %1, 0
+  %asmresult1 = extractvalue { i32, i32 } %1, 1
+  store i32 %asmresult, i32* @a, align 4
+  store i32 %asmresult1, i32* @a, align 4
+  ret i32 0
+}




More information about the llvm-commits mailing list