[PATCH] Fix an assertion caused by using inline asm with indirect register inputs.

Kevin Qin kevinqindev at gmail.com
Wed Mar 12 02:27:13 PDT 2014


Hi,

The regression test in patch came from below C code:

typedef struct {
    float x;
    float y;
    float z;
    float w;
}float4;

float inline_func(float f1, float f2) {
    float4 c1;
    float4 c2;
    float4 c3;

    __asm__ __volatile__ (
            "vmul.f32 %q2, %q0, %q1         \n\t"
            : "=r" (c1), "=r" (c2)
            : "w" (c3)
            :);
    return c3.x;
}

This case would fail in an assertion.  Root cause is, llvm doesn't support indirect register inputs yet. So for handling input description '"w" (c3)', OpInfo.ConstraintVT is calculated to i128 as indirect access, while OpInfo.CallOperand is a FrameIndex, which value type is i32.  Then the bitcast between different width hit an assertion. This patch can fixed this and provide correct diagnostics.

http://llvm-reviews.chandlerc.com/D3052

Files:
  lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
  test/CodeGen/ARM/inline-diagnostics.ll

Index: lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
===================================================================
--- lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -6183,7 +6183,7 @@
       // types are identical size, use a bitcast to convert (e.g. two differing
       // vector types).
       MVT RegVT = *PhysReg.second->vt_begin();
-      if (RegVT.getSizeInBits() == OpInfo.ConstraintVT.getSizeInBits()) {
+      if (RegVT.getSizeInBits() == OpInfo.CallOperand.getValueSizeInBits()) {
         OpInfo.CallOperand = DAG.getNode(ISD::BITCAST, DL,
                                          RegVT, OpInfo.CallOperand);
         OpInfo.ConstraintVT = RegVT;
Index: test/CodeGen/ARM/inline-diagnostics.ll
===================================================================
--- /dev/null
+++ test/CodeGen/ARM/inline-diagnostics.ll
@@ -0,0 +1,16 @@
+; RUN: not llc %s -verify-machineinstrs -mtriple=armv7-none-linux-gnu -mattr=+neon 2>&1 | FileCheck %s
+
+%struct.float4 = type { float, float, float, float }
+
+; CHECK: error: Don't know how to handle indirect register inputs yet for constraint 'w'
+define float @inline_func(float %f1, float %f2) #0 {
+  %c1 = alloca %struct.float4, align 4
+  %c2 = alloca %struct.float4, align 4
+  %c3 = alloca %struct.float4, align 4
+  call void asm sideeffect "vmul.f32 ${2:q}, ${0:q}, ${1:q}", "=*r,=*r,*w"(%struct.float4* %c1, %struct.float4* %c2, %struct.float4* %c3) #1, !srcloc !1
+  %x = getelementptr inbounds %struct.float4* %c3, i32 0, i32 0
+  %1 = load float* %x, align 4
+  ret float %1
+}
+
+!1 = metadata !{i32 271, i32 305}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D3052.1.patch
Type: text/x-patch
Size: 1649 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140312/92c8337b/attachment.bin>


More information about the llvm-commits mailing list