[LLVMbugs] [Bug 8323] New: ScheduleDAGSDNodes.cpp:301: ... "Node already inserted!"

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Thu Oct 7 03:11:41 PDT 2010


           Summary: ScheduleDAGSDNodes.cpp:301: ... "Node already
           Product: libraries
           Version: trunk
          Platform: PC
        OS/Version: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: Backend: ARM
        AssignedTo: unassignedbugs at nondot.org
        ReportedBy: Edmund.Grimley-Evans at arm.com
                CC: llvmbugs at cs.uiuc.edu

Created an attachment (id=5580)
 --> (http://llvm.org/bugs/attachment.cgi?id=5580)
Patch to demonstrate bug

I think this demonstrates a bug in the part of LLVM that handles
Selection DAGs. Unfortunately I can't demonstrate it without patching
LLVM. However, it's a small patch, so someone with the appropriate
experience can probably say very quickly whether the patch itself is

This started off as a much larger patch that did something useful. I've
reduced it to a simple but silly patch that shows the same problem.

Some notes on the patch:

include/llvm/IntrinsicsARM.td: Add three intrinsics: magic_read,
magic_test_eq and magic_test_lt, which each map i32 to i32.

lib/Target/ARM/ARMISelLowering.h: Add three new DAG nodes: MAGIC_TEST
(set the flags), MAGIC_MRS (move flags to register), MAGIC_MSR (move
register to flags).

lib/Target/ARM/ARMInstrThumb2.td: Add an instruction for MAGIC_TEST. We
don't need instructions for the other two nodes as a peephole will
remove them.

lib/Target/ARM/ARMISelLowering.cpp: Two things:

1. In LowerINTRINSIC_WO_CHAIN map magic_read to MAGIC_TEST followed by
MAGIC_MRS, and map magic_test_?? to MAGIC_MSR followed by a CMOV.

2. In PerformDAGCombine shortcircuit magic_MRS followed by magic_MSR.

Now consider an example with magic_read followed by magic_test_eq:

// Debug+Asserts/bin/llc t1.ll

define arm_aapcscc i32 @f13(i32 %a) nounwind readnone {
  %0 = tail call i32 @llvm.arm.magic.read(i32 %a)
  %1 = tail call i32 @llvm.arm.magic.test.eq(i32 %0)
  ret i32 %1

This gets mapped to a sequence of MAGIC_TEST, MAGIC_MRS, MAGIC_MSR,
CMOV. The peephole removes the MRS and MSR, and we're left with
MAGIC_READ followed by CMOV, which turns into:

        magic_test      r0
        mov.w   r0, #0
        it      eq
        moveq   r0, #1
        bx      lr

That's exactly what we expect. But now consider an example where the
output of magic_read is used by both magic_test_eq and magic_test_lt:

// Debug+Asserts/bin/llc t2.ll

define arm_aapcscc i32 @f13(i32 %a) nounwind readnone {
  %0 = tail call i32 @llvm.arm.magic.read(i32 %a)
  %1 = tail call i32 @llvm.arm.magic.test.eq(i32 %0)
  %2 = tail call i32 @llvm.arm.magic.test.lt(i32 %0)
  %add = add nsw i32 %2, %1
  ret i32 %add

Now we get the assertion failure:

llc: ScheduleDAGSDNodes.cpp:301: void
llvm::ScheduleDAGSDNodes::BuildSchedUnits(): Assertion `N->getNodeId() == -1 &&
"Node already inserted!"' failed.

Can anyone confirm that this represents a bug?

Configure bugmail: http://llvm.org/bugs/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.

More information about the llvm-bugs mailing list