[llvm-commits] [llvm] r165072 - in /llvm/trunk: lib/Target/X86/X86ISelDAGToDAG.cpp test/CodeGen/X86/2012-10-02-DAGCycle.ll

Benjamin Kramer benny.kra at gmail.com
Thu Oct 4 11:37:18 PDT 2012


On 03.10.2012, at 01:49, Evan Cheng <evan.cheng at apple.com> wrote:

> Author: evancheng
> Date: Tue Oct  2 18:49:13 2012
> New Revision: 165072
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=165072&view=rev
> Log:
> Fix a serious X86 instruction selection bug. In
> X86DAGToDAGISel::PreprocessISelDAG(), isel is moving load inside
> callseq_start / callseq_end so it can be folded into a call. This can
> create a cycle in the DAG when the call is glued to a copytoreg. We
> have been lucky this hasn't caused too many issues because the pre-ra
> scheduler has special handling of call sequences. However, it has
> caused a crash in a specific tailcall case.

This commit breaks compiling bullet from the test-suite:

$ cd test-suite/MultiSource/Benchmarks/Bullet
$ clang++ -Iinclude -DNO_TIME -c btConeShape.cpp -O3 -o /dev/null

# Machine code for function _ZNK11btConeShape24localGetSupportingVertexERK9btVector3: Post SSA
Constant Pool:
  cp#0: float -1.000000e+00, align=4
  cp#1: float 0x3D10000000000000, align=4
  cp#2: float 1.000000e+00, align=4
Function Live Ins: %RDI in %vreg6, %RSI in %vreg7
Function Live Outs: %XMM0 %XMM1

BB#0: derived from LLVM BB %entry
    Live Ins: %RDI %RSI
	%vreg7<def> = COPY %RSI<kill>; GR64:%vreg7
	%vreg6<def> = COPY %RDI<kill>; GR64:%vreg6
	ADJCALLSTACKDOWN64 0, %RSP<imp-def>, %EFLAGS<imp-def,dead>, %RSP<imp-use>
	%RDI<def> = COPY %vreg6; GR64:%vreg6
	%RSI<def> = COPY %vreg7; GR64:%vreg7
	CALL64pcrel32 <ga:@_ZNK11btConeShape16coneLocalSupportERK9btVector3>, <regmask>, %RSP<imp-use>, %RDI<imp-use>, %RSI<imp-use,kill>, %RSP<imp-def>, %XMM0<imp-def>, %XMM1<imp-def>
	ADJCALLSTACKUP64 0, 0, %RSP<imp-def>, %EFLAGS<imp-def,dead>, %RSP<imp-use>
	%vreg8<def> = COPY %XMM0<kill>; VR128:%vreg8
	%vreg9<def> = COPY %XMM1<kill>; VR128:%vreg9
	%vreg10<def> = MOV64rm %vreg6, 1, %noreg, 0, %noreg; mem:LD8[%3](tbaa=!"vtable pointer") GR64:%vreg10,%vreg6
	ADJCALLSTACKDOWN64 0, %RSP<imp-def>, %EFLAGS<imp-def,dead>, %RSP<imp-use>
	%RDI<def> = COPY %vreg6; GR64:%vreg6
	CALL64m %vreg10<kill>, 1, %noreg, 88, %noreg, <regmask>, %RSP<imp-use>, %RDI<imp-use>, %RSP<imp-def>, %XMM0<imp-def>; mem:LD8[%vfn] GR64:%vreg10
	ADJCALLSTACKUP64 0, 0, %RSP<imp-def>, %EFLAGS<imp-def,dead>, %RSP<imp-use>
	%vreg11<def> = COPY %XMM0<kill>; FR32:%vreg11
	%vreg1<def> = COPY %vreg9<kill>; VR128:%vreg1,%vreg9
	%vreg0<def> = COPY %vreg8<kill>; VR128:%vreg0,%vreg8
	%vreg12<def> = FsFLD0SS; FR32:%vreg12
	UCOMISSrr %vreg11<kill>, %vreg12<kill>, %EFLAGS<imp-def>; FR32:%vreg11,%vreg12
	JNE_4 <BB#1>, %EFLAGS<imp-use>
	JP_4 <BB#1>, %EFLAGS<imp-use,kill>
    Successors according to CFG: BB#1(20) BB#9(12)

BB#9: 
    Predecessors according to CFG: BB#0
	%vreg58<def> = COPY %vreg1<kill>; VR128:%vreg58,%vreg1
	%vreg59<def> = COPY %vreg0<kill>; VR128:%vreg59,%vreg0
	JMP_4 <BB#8>
    Successors according to CFG: BB#8

BB#1: derived from LLVM BB %if.then
    Predecessors according to CFG: BB#0
	%vreg13<def> = MOVSSrm %vreg7, 1, %noreg, 0, %noreg; mem:LD4[%vecnorm.sroa.0.0..idx39] FR32:%vreg13 GR64:%vreg7
	%vreg14<def> = MOVSSrm %vreg7, 1, %noreg, 4, %noreg; mem:LD4[%vecnorm.sroa.1.4..idx26] FR32:%vreg14 GR64:%vreg7
	%vreg15<def> = COPY %vreg14; FR32:%vreg15,%vreg14
	%vreg15<def,tied1> = MULSSrr %vreg15<tied0>, %vreg15; FR32:%vreg15
	%vreg16<def> = COPY %vreg13; FR32:%vreg16,%vreg13
	%vreg16<def,tied1> = MULSSrr %vreg16<tied0>, %vreg16; FR32:%vreg16
	%vreg17<def> = COPY %vreg16<kill>; FR32:%vreg17,%vreg16
	%vreg17<def,tied1> = ADDSSrr %vreg17<tied0>, %vreg15<kill>; FR32:%vreg17,%vreg15
	%vreg18<def> = MOVSSrm %vreg7<kill>, 1, %noreg, 8, %noreg; mem:LD4[%vecnorm.sroa.2.8..idx27] FR32:%vreg18 GR64:%vreg7
	%vreg19<def> = COPY %vreg18; FR32:%vreg19,%vreg18
	%vreg19<def,tied1> = MULSSrr %vreg19<tied0>, %vreg19; FR32:%vreg19
	%vreg20<def> = COPY %vreg19<kill>; FR32:%vreg20,%vreg19
	%vreg20<def,tied1> = ADDSSrr %vreg20<tied0>, %vreg17<kill>; FR32:%vreg20,%vreg17
	%vreg21<def> = MOV64rm %vreg6<kill>, 1, %noreg, 0, %noreg; mem:LD8[%5](tbaa=!"vtable pointer") GR64:%vreg21,%vreg6
	ADJCALLSTACKDOWN64 0, %RSP<imp-def>, %EFLAGS<imp-def,dead>, %RSP<imp-use>
	%vreg22<def> = MOVSSrm %RIP, 1, %noreg, <cp#0>, %noreg; mem:LD4[ConstantPool] FR32:%vreg22
	%vreg23<def> = MOVSSrm %RIP, 1, %noreg, <cp#1>, %noreg; mem:LD4[ConstantPool] FR32:%vreg23
	UCOMISSrr %vreg23<kill>, %vreg20<kill>, %EFLAGS<imp-def>; FR32:%vreg23,%vreg20
	%vreg55<def> = COPY %vreg22; FR32:%vreg55,%vreg22
	JA_4 <BB#3>, %EFLAGS<imp-use>
    Successors according to CFG: BB#2 BB#3

BB#2: derived from LLVM BB %if.then
    Live Ins: %EFLAGS
    Predecessors according to CFG: BB#1
	%vreg55<def> = COPY %vreg14<kill>; FR32:%vreg55,%vreg14
    Successors according to CFG: BB#3

BB#3: derived from LLVM BB %if.then
    Live Ins: %EFLAGS
    Predecessors according to CFG: BB#1 BB#2
	%vreg24<def> = COPY %vreg55<kill>; FR32:%vreg24,%vreg55
	%vreg56<def> = COPY %vreg22; FR32:%vreg56,%vreg22
	JA_4 <BB#5>, %EFLAGS<imp-use>
    Successors according to CFG: BB#4 BB#5

BB#4: derived from LLVM BB %if.then
    Live Ins: %EFLAGS
    Predecessors according to CFG: BB#3
	%vreg56<def> = COPY %vreg18<kill>; FR32:%vreg56,%vreg18
    Successors according to CFG: BB#5

BB#5: derived from LLVM BB %if.then
    Live Ins: %EFLAGS
    Predecessors according to CFG: BB#3 BB#4
	%vreg25<def> = COPY %vreg56<kill>; FR32:%vreg25,%vreg56
	%vreg26<def> = COPY %vreg24; FR32:%vreg26,%vreg24
	%vreg26<def,tied1> = MULSSrr %vreg26<tied0>, %vreg26; FR32:%vreg26
	%vreg57<def> = COPY %vreg22<kill>; FR32:%vreg57,%vreg22
	JA_4 <BB#7>, %EFLAGS<imp-use,kill>
    Successors according to CFG: BB#6 BB#7

BB#6: derived from LLVM BB %if.then
    Predecessors according to CFG: BB#5
	%vreg57<def> = COPY %vreg13<kill>; FR32:%vreg57,%vreg13
    Successors according to CFG: BB#7

BB#7: derived from LLVM BB %if.then
    Predecessors according to CFG: BB#5 BB#6
	%vreg27<def> = COPY %vreg57<kill>; FR32:%vreg27,%vreg57
	CALL64m %vreg21<kill>, 1, %noreg, 88, %noreg, <regmask>, %RSP<imp-use>, %RDI<imp-use>, %RSP<imp-def>, %XMM0<imp-def>; mem:LD8[%vfn11] GR64:%vreg21
	ADJCALLSTACKUP64 0, 0, %RSP<imp-def>, %EFLAGS<imp-def,dead>, %RSP<imp-use>
	%vreg28<def> = COPY %XMM0<kill>; FR32:%vreg28
	%vreg29<def> = PSHUFDri %vreg0, 1; VR128:%vreg29,%vreg0
	%vreg30<def> = PSHUFDri %vreg1, 1; VR128:%vreg30,%vreg1
	%vreg31<def> = COPY %vreg30<kill>; VR128:%vreg31,%vreg30
	%vreg35<def> = COPY %vreg27; FR32:%vreg35,%vreg27
	%vreg35<def,tied1> = MULSSrr %vreg35<tied0>, %vreg35; FR32:%vreg35
	%vreg36<def> = COPY %vreg35<kill>; FR32:%vreg36,%vreg35
	%vreg36<def,tied1> = ADDSSrr %vreg36<tied0>, %vreg26<kill>; FR32:%vreg36,%vreg26
	%vreg38<def> = COPY %vreg25; FR32:%vreg38,%vreg25
	%vreg38<def,tied1> = MULSSrr %vreg38<tied0>, %vreg38; FR32:%vreg38
	%vreg39<def> = COPY %vreg38<kill>; FR32:%vreg39,%vreg38
	%vreg39<def,tied1> = ADDSSrr %vreg39<tied0>, %vreg36<kill>; FR32:%vreg39,%vreg36
	%vreg40<def> = SQRTSSr %vreg39<kill>; FR32:%vreg40,%vreg39
	%vreg41<def> = MOVSSrm %RIP, 1, %noreg, <cp#2>, %noreg; mem:LD4[ConstantPool] FR32:%vreg41
	%vreg42<def> = COPY %vreg41<kill>; FR32:%vreg42,%vreg41
	%vreg42<def,tied1> = DIVSSrr %vreg42<tied0>, %vreg40<kill>; FR32:%vreg42,%vreg40
	%vreg43<def> = COPY %vreg24<kill>; FR32:%vreg43,%vreg24
	%vreg43<def,tied1> = MULSSrr %vreg43<tied0>, %vreg42; FR32:%vreg43,%vreg42
	%vreg44<def> = COPY %vreg43<kill>; FR32:%vreg44,%vreg43
	%vreg44<def,tied1> = MULSSrr %vreg44<tied0>, %vreg28; FR32:%vreg44,%vreg28
	%vreg45<def> = COPY %vreg44<kill>; VR128:%vreg45 FR32:%vreg44
	%vreg45<def,tied1> = ADDSSrr %vreg45<tied0>, %vreg29<kill>; VR128:%vreg45,%vreg29
	%vreg47<def> = COPY %vreg27<kill>; FR32:%vreg47,%vreg27
	%vreg47<def,tied1> = MULSSrr %vreg47<tied0>, %vreg42; FR32:%vreg47,%vreg42
	%vreg48<def> = COPY %vreg47<kill>; FR32:%vreg48,%vreg47
	%vreg48<def,tied1> = MULSSrr %vreg48<tied0>, %vreg28; FR32:%vreg48,%vreg28
	%vreg49<def> = COPY %vreg48<kill>; VR128:%vreg49 FR32:%vreg48
	%vreg49<def,tied1> = ADDSSrr %vreg49<tied0>, %vreg0<kill>; VR128:%vreg49,%vreg0
	%vreg2<def> = COPY %vreg49<kill>; VR128:%vreg2,%vreg49
	%vreg2<def,tied1> = UNPCKLPSrr %vreg2<tied0>, %vreg45<kill>; VR128:%vreg2,%vreg45
	%vreg51<def> = COPY %vreg42<kill>; FR32:%vreg51,%vreg42
	%vreg51<def,tied1> = MULSSrr %vreg51<tied0>, %vreg25<kill>; FR32:%vreg51,%vreg25
	%vreg52<def> = COPY %vreg51<kill>; FR32:%vreg52,%vreg51
	%vreg52<def,tied1> = MULSSrr %vreg52<tied0>, %vreg28<kill>; FR32:%vreg52,%vreg28
	%vreg53<def> = COPY %vreg52<kill>; VR128:%vreg53 FR32:%vreg52
	%vreg53<def,tied1> = ADDSSrr %vreg53<tied0>, %vreg1<kill>; VR128:%vreg53,%vreg1
	%vreg3<def> = COPY %vreg53<kill>; VR128:%vreg3,%vreg53
	%vreg3<def,tied1> = UNPCKLPSrr %vreg3<tied0>, %vreg31<kill>; VR128:%vreg3,%vreg31
	%vreg58<def> = COPY %vreg3<kill>; VR128:%vreg58,%vreg3
	%vreg59<def> = COPY %vreg2<kill>; VR128:%vreg59,%vreg2
    Successors according to CFG: BB#8

BB#8: derived from LLVM BB %if.end17
    Predecessors according to CFG: BB#7 BB#9
	%vreg4<def> = COPY %vreg58<kill>; VR128:%vreg4,%vreg58
	%vreg5<def> = COPY %vreg59<kill>; VR128:%vreg5,%vreg59
	%XMM0<def> = COPY %vreg5<kill>; VR128:%vreg5
	%XMM1<def> = COPY %vreg4<kill>; VR128:%vreg4
	RET %XMM0<imp-use,kill>, %XMM1<imp-use,kill>

# End machine code for function _ZNK11btConeShape24localGetSupportingVertexERK9btVector3.

*** Bad machine code: Using an undefined physical register ***
- function:    _ZNK11btConeShape24localGetSupportingVertexERK9btVector3
- basic block: BB#7 if.then (0x7fc829b6b648)
- instruction: CALL64m %vreg21<kill>, 1, %noreg, 88, %noreg, <regmask>, %RSP<imp-use>, %RDI<imp-use>, %RSP<imp-def>, %XMM0<imp-def>; mem:LD8[%vfn11] GR64:%vreg21
- operand 7:   %RDI<imp-use>
fatal error: error in backend: Found 1 machine code errors.


> 
> rdar://12393897
> 
> Added:
>    llvm/trunk/test/CodeGen/X86/2012-10-02-DAGCycle.ll
> Modified:
>    llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp
> 
> Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp?rev=165072&r1=165071&r2=165072&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp (original)
> +++ llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Tue Oct  2 18:49:13 2012
> @@ -362,7 +362,7 @@
> /// MoveBelowCallOrigChain - Replace the original chain operand of the call with
> /// load's chain operand and move load below the call's chain operand.
> static void MoveBelowOrigChain(SelectionDAG *CurDAG, SDValue Load,
> -                                  SDValue Call, SDValue OrigChain) {
> +                               SDValue Call, SDValue OrigChain) {
>   SmallVector<SDValue, 8> Ops;
>   SDValue Chain = OrigChain.getOperand(0);
>   if (Chain.getNode() == Load.getNode())
> @@ -386,11 +386,22 @@
>   CurDAG->UpdateNodeOperands(OrigChain.getNode(), &Ops[0], Ops.size());
>   CurDAG->UpdateNodeOperands(Load.getNode(), Call.getOperand(0),
>                              Load.getOperand(1), Load.getOperand(2));
> +
> +  bool IsGlued = Call.getOperand(0).getNode()->getGluedUser() == Call.getNode();
> +  unsigned NumOps = Call.getNode()->getNumOperands();
>   Ops.clear();
>   Ops.push_back(SDValue(Load.getNode(), 1));
> -  for (unsigned i = 1, e = Call.getNode()->getNumOperands(); i != e; ++i)
> +  for (unsigned i = 1, e = NumOps; i != e; ++i)
>     Ops.push_back(Call.getOperand(i));
> -  CurDAG->UpdateNodeOperands(Call.getNode(), &Ops[0], Ops.size());
> +  if (!IsGlued)
> +    CurDAG->UpdateNodeOperands(Call.getNode(), &Ops[0], NumOps);
> +  else
> +    // If call's chain was glued to the call (tailcall), and now the load
> +    // is moved between them. Remove the glue to avoid a cycle (where the
> +    // call is glued to its old chain and the load is using the old chain
> +    // as its new chain).
> +    CurDAG->MorphNodeTo(Call.getNode(), Call.getOpcode(),
> +                        Call.getNode()->getVTList(), &Ops[0], NumOps-1);
> }
> 
> /// isCalleeLoad - Return true if call address is a load and it can be
> 
> Added: llvm/trunk/test/CodeGen/X86/2012-10-02-DAGCycle.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2012-10-02-DAGCycle.ll?rev=165072&view=auto
> ==============================================================================
> --- llvm/trunk/test/CodeGen/X86/2012-10-02-DAGCycle.ll (added)
> +++ llvm/trunk/test/CodeGen/X86/2012-10-02-DAGCycle.ll Tue Oct  2 18:49:13 2012
> @@ -0,0 +1,16 @@
> +; RUN: llc -mtriple=i386-apple-macosx -relocation-model=pic < %s
> +; rdar://12393897
> +
> +%TRp = type { i32, %TRH*, i32, i32 }
> +%TRH = type { i8*, i8*, i8*, i8*, {}* }
> +
> +define i32 @t(%TRp* inreg %rp) nounwind optsize ssp {
> +entry:
> +  %handler = getelementptr inbounds %TRp* %rp, i32 0, i32 1
> +  %0 = load %TRH** %handler, align 4
> +  %sync = getelementptr inbounds %TRH* %0, i32 0, i32 4
> +  %sync12 = load {}** %sync, align 4
> +  %1 = bitcast {}* %sync12 to i32 (%TRp*)*
> +  %call = tail call i32 %1(%TRp* inreg %rp) nounwind optsize
> +  ret i32 %call
> +}
> 
> 
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits





More information about the llvm-commits mailing list