Boris Boesler via llvm-dev
2015-Dec-02 17:11 UTC
[llvm-dev] Assertion failed: "Node emitted out of order - late"
Hi! I get the error 'Assertion failed: (I != VRBaseMap.end() && "Node emitted out of order - late")' in a simple test function. LLVM dis-assembly looks like this: ; Function Attrs: nounwind define void @bug(i32* nocapture readnone %result, i32* nocapture readonly %sptr) #0 { entry: %a = alloca [16 x i32], align 8 %0 = bitcast [16 x i32]* %a to i8* call void @llvm.lifetime.start(i64 64, i8* %0) #1 %arraydecay = getelementptr inbounds [16 x i32]* %a, i16 0, i16 0 %sptr.addr.010 = getelementptr inbounds i32* %sptr, i16 1 %v.0 = load i32* %sptr, align 8 %cmp1 = icmp eq i32 %v.0, 0 br i1 %cmp1, label %if.end, label %if.then if.then: ; preds = %entry After scheduling there is a CopyToReg node and a llvm.lifetime.start node, both have a TargetFrameIndex<0> as operand (it is a TargetFrameIndex from the very first pass - but I expected a FrameIndex). I guess this is %a. The instruction emitter tries to get the virtual register number from the CopyToReg's operand, the TargetFrameIndex. But there is no virtual register number for TargetFrameIndex and that raises the assertion. Well, I have lots of [Target]FrameIndex operations in other test code, but probably no arrays, and that works as expected. I do not touch the llvm.lifetime.X intrinsics. I can leave them, right? What did I miss to do? Why is there no virtual register for that TargetFrameIndex? Thanks, Boris
Boris Boesler via llvm-dev
2015-Dec-10 15:26 UTC
[llvm-dev] Assertion failed: "Node emitted out of order - late"
> I get the error 'Assertion failed: (I != VRBaseMap.end() && "Node emitted out of order - late")' in a simple test function. LLVM dis-assembly looks like this:[full disassembly and original code at the end]> After scheduling there is a CopyToReg node and a llvm.lifetime.start node, both have a TargetFrameIndex<0> as operand (it is a TargetFrameIndex from the very first pass - but I expected a FrameIndex). I guess this is %a. The instruction emitter tries to get the virtual register number from the CopyToReg's operand, the TargetFrameIndex. But there is no virtual register number for TargetFrameIndex and that raises the assertion. > Well, I have lots of [Target]FrameIndex operations in other test code, but probably no arrays, and that works as expected. > > I do not touch the llvm.lifetime.X intrinsics. I can leave them, right? > What did I miss to do? Why is there no virtual register for that TargetFrameIndex?I worked on that a little bit more: the TargetFrameIndex is only used by CopToReg and llvm.lifetime.start; it seems that these operations do not trigger the generation of virtual registers? If I add some access/write to that array a[0]=0; in the entry block, then the generation of the virtual register is triggered. I compared "my" IR graphs to the IR graphs generated by the ARM backend: the ARM backend generates an extra "ADD #0" and gets a virtual register number. I'm really stuck and need some help. Boris --8<-- void bug_no190 (int* result, int *sptr, int end_index) { int a[16]; int *cptr = a; int v = *sptr++; //a[0] = 0; // this avoids the crash for(int i = 1; i < 3; i++) { if(v != 0) { *cptr++ = 0; } v = *sptr++; } } --8<-- ; Function Attrs: nounwind define void @bug_no190(i32* nocapture readnone %result, i32* nocapture readonly %sptr, i32 %end_index) #0 { entry: %a = alloca [16 x i32], align 8 %0 = bitcast [16 x i32]* %a to i8* call void @llvm.lifetime.start(i64 64, i8* %0) #1 %arraydecay = getelementptr inbounds [16 x i32]* %a, i16 0, i16 0 %sptr.addr.010 = getelementptr inbounds i32* %sptr, i16 1 %v.0 = load i32* %sptr, align 8 %cmp1 = icmp eq i32 %v.0, 0 br i1 %cmp1, label %if.end, label %if.then if.then: ; preds = %entry %incdec.ptr2 = getelementptr inbounds [16 x i32]* %a, i16 0, i16 1 store i32 0, i32* %arraydecay, align 8, !tbaa !1 br label %if.end if.end: ; preds = %if.then, %entry %cptr.1 = phi i32* [ %incdec.ptr2, %if.then ], [ %arraydecay, %entry ] %v.0.1 = load i32* %sptr.addr.010, align 8 %cmp1.1 = icmp eq i32 %v.0.1, 0 br i1 %cmp1.1, label %if.end.1, label %if.then.1 if.then.1: ; preds = %if.end store i32 0, i32* %cptr.1, align 8, !tbaa !1 br label %if.end.1 if.end.1: ; preds = %if.then.1, %if.end call void @llvm.lifetime.end(i64 64, i8* %0) #1 ret void } ; Function Attrs: nounwind declare void @llvm.lifetime.start(i64, i8* nocapture) #1 ; Function Attrs: nounwind declare void @llvm.lifetime.end(i64, i8* nocapture) #1 attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } attributes #1 = { nounwind } !llvm.ident = !{!0} !0 = metadata !{metadata !"clang version 3.4.2 (tags/RELEASE_34/dot2-final)"} !1 = metadata !{metadata !2, metadata !2, i64 0} !2 = metadata !{metadata !"int", metadata !3, i64 0} !3 = metadata !{metadata !"omnipotent char", metadata !4, i64 0} !4 = metadata !{metadata !"Simple C/C++ TBAA"}