1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-24 11:42:57 +01:00

[DAGCombiner] Fix DebugLoc propagation when folding !(x cc y) -> (x !cc y)

Summary:
Currently, when 't1: i1 = setcc t2, t3, cc' followed by 't4: i1 = xor t1, Constant:i1<-1>' is folded into 't5: i1 = setcc t2, t3 !cc', SDLoc of newly created SDValue 't5' follows SDLoc of 't4', not 't1'. However, as the opcode of newly created SDValue is 'setcc', it make more sense to take DebugLoc from 't1' than 't4'. For the code below

```
extern int bar();
extern int baz();

int foo(int x, int y) {
  if (x != y)
    return bar();
  else
    return baz();
}
```

, following is the bitcode representation of 'foo' at the end of llvm-ir level optimization:

```
define i32 @foo(i32 %x, i32 %y) !dbg !4 {
entry:
  tail call void @llvm.dbg.value(metadata i32 %x, i64 0, metadata !9, metadata !11), !dbg !12
  tail call void @llvm.dbg.value(metadata i32 %y, i64 0, metadata !10, metadata !11), !dbg !13
  %cmp = icmp ne i32 %x, %y, !dbg !14
  br i1 %cmp, label %if.then, label %if.else, !dbg !16

if.then:                                          ; preds = %entry
  %call = tail call i32 (...) @bar() #3, !dbg !17
  br label %return, !dbg !18

if.else:                                          ; preds = %entry
  %call1 = tail call i32 (...) @baz() #3, !dbg !19
  br label %return, !dbg !20

return:                                           ; preds = %if.else, %if.then
  %retval.0 = phi i32 [ %call, %if.then ], [ %call1, %if.else ]
  ret i32 %retval.0, !dbg !21
}

!14 = !DILocation(line: 5, column: 9, scope: !15)
!16 = !DILocation(line: 5, column: 7, scope: !4)

```

As you can see, in 'entry' block, 'icmp' instruction and 'br' instruction have different debug locations. However, with current implementation, there's no distinction between debug locations of these two when they are lowered to asm instructions. This is because 'icmp' and 'br' become 'setcc' 'xor' and 'brcond' in SelectionDAG, where SDLoc of 'setcc' follows the debug location of 'icmp' but SDLOC of 'xor' and 'brcond' follows the debug location of 'br' instruction, and SDLoc of 'xor' overwrites SDLoc of 'setcc' when they are folded. This patch addresses this issue.

Reviewers: atrick, bogner, andreadb, craig.topper, aprantl

Reviewed By: andreadb

Subscribers: jlebar, mkuper, jholewinski, andreadb, llvm-commits

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

llvm-svn: 296825
This commit is contained in:
Taewook Oh 2017-03-02 21:58:35 +00:00
parent 242e96e9e4
commit 6d132686e0
6 changed files with 95 additions and 26 deletions

View File

@ -4856,9 +4856,9 @@ SDValue DAGCombiner::visitXOR(SDNode *N) {
default:
llvm_unreachable("Unhandled SetCC Equivalent!");
case ISD::SETCC:
return DAG.getSetCC(SDLoc(N), VT, LHS, RHS, NotCC);
return DAG.getSetCC(SDLoc(N0), VT, LHS, RHS, NotCC);
case ISD::SELECT_CC:
return DAG.getSelectCC(SDLoc(N), LHS, RHS, N0.getOperand(2),
return DAG.getSelectCC(SDLoc(N0), LHS, RHS, N0.getOperand(2),
N0.getOperand(3), NotCC);
}
}

View File

@ -114,8 +114,8 @@ entry:
; PTX-LABEL: .visible .func (.param .b64 func_retval0) memmove_caller(
; PTX: ld.param.u64 %rd[[N:[0-9]+]]
; PTX: setp.eq.s64 %p[[NEQ0:[0-9]+]], %rd[[N]], 0
; PTX: setp.ge.u64 %p[[SRC_GT_THAN_DST:[0-9]+]], %rd{{[0-9]+}}, %rd{{[0-9]+}}
; PTX-DAG: setp.eq.s64 %p[[NEQ0:[0-9]+]], %rd[[N]], 0
; PTX-DAG: setp.ge.u64 %p[[SRC_GT_THAN_DST:[0-9]+]], %rd{{[0-9]+}}, %rd{{[0-9]+}}
; PTX-NEXT: @%p[[SRC_GT_THAN_DST]] bra LBB[[FORWARD_BB:[0-9_]+]]
; -- this is the backwards copying BB
; PTX: @%p[[NEQ0]] bra LBB[[EXIT:[0-9_]+]]

View File

@ -80,8 +80,8 @@ define i32 @and_sink3(i1 %c, i32* %p) {
; CHECK: testb $1,
; CHECK: je
; CHECK: movzbl
; CHECK: movl $0, A
; CHECK: testl %
; CHECK-DAG: movl $0, A
; CHECK-DAG: testl %
; CHECK: je
; CHECK-CGP-LABEL: @and_sink3(
@ -109,11 +109,11 @@ define i32 @and_sink4(i32 %a, i32 %b, i1 %c) {
; CHECK: testb $1,
; CHECK: je
; CHECK-NOT: andl
; CHECK: movl $0, A
; CHECK: testl [[REG1:%[a-z0-9]+]], [[REG2:%[a-z0-9]+]]
; CHECK-DAG: movl $0, A
; CHECK-DAG: testl [[REG1:%[a-z0-9]+]], [[REG2:%[a-z0-9]+]]
; CHECK: jne
; CHECK: movl {{%[a-z0-9]+}}, B
; CHECK: testl [[REG1]], [[REG2]]
; CHECK-DAG: movl {{%[a-z0-9]+}}, B
; CHECK-DAG: testl [[REG1]], [[REG2]]
; CHECK: je
; CHECK-CGP-LABEL: @and_sink4(
@ -148,11 +148,11 @@ define i32 @and_sink5(i32 %a, i32 %b, i32 %a2, i32 %b2, i1 %c) {
; CHECK-LABEL: and_sink5:
; CHECK: testb $1,
; CHECK: je
; CHECK: andl {{[0-9]+\(%[a-z0-9]+\)}}, [[REG:%[a-z0-9]+]]
; CHECK: movl $0, A
; CHECK-DAG: andl {{[0-9]+\(%[a-z0-9]+\)}}, [[REG:%[a-z0-9]+]]
; CHECK-DAG: movl $0, A
; CHECK: jne
; CHECK: movl {{%[a-z0-9]+}}, B
; CHECK: testl [[REG]], [[REG]]
; CHECK-DAG: movl {{%[a-z0-9]+}}, B
; CHECK-DAG: testl [[REG]], [[REG]]
; CHECK: je
; CHECK-CGP-LABEL: @and_sink5(

View File

@ -12,19 +12,19 @@ define i32 @test(float %a, float %b) {
; CHECK-NEXT: .cfi_def_cfa_offset 16
; CHECK-NEXT: movb $1, %al
; CHECK-NEXT: vucomiss %xmm1, %xmm0
; CHECK-NEXT: setnp %cl
; CHECK-NEXT: sete %dl
; CHECK-NEXT: setp %sil
; CHECK-NEXT: setne %dil
; CHECK-NEXT: andb %cl, %dl
; CHECK-NEXT: ## implicit-def: %R8D
; CHECK-NEXT: movb %dl, %r8b
; CHECK-NEXT: andl $1, %r8d
; CHECK-NEXT: kmovw %r8d, %k0
; CHECK-NEXT: orb %sil, %dil
; CHECK-NEXT: setp %cl
; CHECK-NEXT: setne %dl
; CHECK-NEXT: setnp %sil
; CHECK-NEXT: sete %dil
; CHECK-NEXT: andb %sil, %dil
; CHECK-NEXT: ## implicit-def: %R8D
; CHECK-NEXT: movb %dil, %r8b
; CHECK-NEXT: andl $1, %r8d
; CHECK-NEXT: kmovw %r8d, %k0
; CHECK-NEXT: orb %cl, %dl
; CHECK-NEXT: ## implicit-def: %R8D
; CHECK-NEXT: movb %dl, %r8b
; CHECK-NEXT: andl $1, %r8d
; CHECK-NEXT: kmovw %r8d, %k1
; CHECK-NEXT: kmovw %k1, %ecx
; CHECK-NEXT: testb $1, %cl

View File

@ -306,10 +306,10 @@ cleanup: ; preds = %entry, %if.then
ret void
; CHECK-LABEL: TestCopySign
; CHECK-NOT: call
; CHECK: callq __subtf3
; CHECK-NOT: call
; CHECK: callq __gttf2
; CHECK-NOT: call
; CHECK: callq __subtf3
; CHECK-NOT: call
; CHECK: andps {{.*}}, %xmm0
; CHECK: retq
}

View File

@ -0,0 +1,69 @@
; RUN: llc -stop-after=expand-isel-pseudos < %s | FileCheck %s
;
; Make sure that when the entry block of IR below is lowered, an instruction
; that implictly defines %eflags has a same debug location with the icmp
; instruction, and the branch instructions have a same debug location with the
; br instruction.
;
; CHECK: [[DLOC1:![0-9]+]] = !DILocation(line: 5, column: 9, scope: !{{[0-9]+}})
; CHECK: [[DLOC2:![0-9]+]] = !DILocation(line: 5, column: 7, scope: !{{[0-9]+}})
; CHECK-DAG: [[VREG1:%[^ ]+]] = COPY %esi
; CHECK-DAG: [[VREG2:%[^ ]+]] = COPY %edi
; CHECK: SUB32rr [[VREG2]], [[VREG1]], implicit-def %eflags, debug-location [[DLOC1]]
; CHECK-NEXT: JE_1{{.*}} implicit %eflags, debug-location [[DLOC2]]
; CHECK-NEXT: JMP_1{{.*}} debug-location [[DLOC2]]
target triple = "x86_64-unknown-linux-gnu"
; Function Attrs: nounwind uwtable
define i32 @foo(i32 %x, i32 %y) !dbg !4 {
entry:
tail call void @llvm.dbg.value(metadata i32 %x, i64 0, metadata !9, metadata !11), !dbg !12
tail call void @llvm.dbg.value(metadata i32 %y, i64 0, metadata !10, metadata !11), !dbg !13
%cmp = icmp ne i32 %x, %y, !dbg !14
br i1 %cmp, label %if.then, label %if.else, !dbg !16
if.then: ; preds = %entry
%call = tail call i32 (...) @bar() #3, !dbg !17
br label %return, !dbg !18
if.else: ; preds = %entry
%call1 = tail call i32 (...) @baz() #3, !dbg !19
br label %return, !dbg !20
return: ; preds = %if.else, %if.then
%retval.0 = phi i32 [ %call, %if.then ], [ %call1, %if.else ]
ret i32 %retval.0, !dbg !21
}
declare i32 @bar(...)
declare i32 @baz(...)
; Function Attrs: nounwind readnone
declare void @llvm.dbg.value(metadata, i64, metadata, metadata)
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!2, !3}
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, emissionKind: FullDebug)
!1 = !DIFile(filename: "foo.c", directory: "b/")
!2 = !{i32 2, !"Dwarf Version", i32 4}
!3 = !{i32 2, !"Debug Info Version", i32 3}
!4 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 4, type: !5, isLocal: false, isDefinition: true, scopeLine: 4, flags: DIFlagPrototyped, isOptimized: true, unit: !0, variables: !8)
!5 = !DISubroutineType(types: !6)
!6 = !{!7, !7, !7}
!7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!8 = !{!9, !10}
!9 = !DILocalVariable(name: "x", arg: 1, scope: !4, file: !1, line: 4, type: !7)
!10 = !DILocalVariable(name: "y", arg: 2, scope: !4, file: !1, line: 4, type: !7)
!11 = !DIExpression()
!12 = !DILocation(line: 4, column: 13, scope: !4)
!13 = !DILocation(line: 4, column: 20, scope: !4)
!14 = !DILocation(line: 5, column: 9, scope: !15)
!15 = distinct !DILexicalBlock(scope: !4, file: !1, line: 5, column: 7)
!16 = !DILocation(line: 5, column: 7, scope: !4)
!17 = !DILocation(line: 6, column: 12, scope: !15)
!18 = !DILocation(line: 6, column: 5, scope: !15)
!19 = !DILocation(line: 8, column: 12, scope: !15)
!20 = !DILocation(line: 8, column: 5, scope: !15)
!21 = !DILocation(line: 9, column: 1, scope: !4)