[DAGCombiner] Fix DebugLoc propagation when folding !(x cc y) -> (x !cc y)
authorTaewook Oh <twoh@fb.com>
Thu, 2 Mar 2017 21:58:35 +0000 (21:58 +0000)
committerTaewook Oh <twoh@fb.com>
Thu, 2 Mar 2017 21:58:35 +0000 (21:58 +0000)
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

llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
llvm/test/CodeGen/NVPTX/lower-aggr-copies.ll
llvm/test/CodeGen/X86/and-sink.ll
llvm/test/CodeGen/X86/avx512-fsel.ll
llvm/test/CodeGen/X86/fp128-i128.ll
llvm/test/CodeGen/X86/xor-combine-debugloc.ll [new file with mode: 0644]

index 2f6a26d319f4b41e5da34d115e5aaea7c942f2e6..921b1f4284a7a2ae57cdfae8344b632167e1a0be 100644 (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);
       }
     }
index f593969f2a49327cd3bb3acc4c98ccc181dd222f..192d4becb05963fdb8fe36e1d30bcdbc15e23e77 100644 (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_]+]]
index 18120d7f78648fbe3e945667c83bd427cd85d95f..46e50f2a6a74e54b37e71ac5c3d0babddf0df5fe 100644 (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(
index c6f2da6ff60b82c02275402fe786f24dd446600c..2f52ecd23e9b7fb456c47d6fc31812f4e86f8a70 100644 (file)
@@ -12,18 +12,18 @@ 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:    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 %dl, %r8b
+; CHECK-NEXT:    movb %dil, %r8b
 ; CHECK-NEXT:    andl $1, %r8d
 ; CHECK-NEXT:    kmovw %r8d, %k0
-; CHECK-NEXT:    orb %sil, %dil
+; CHECK-NEXT:    orb %cl, %dl
 ; CHECK-NEXT:    ## implicit-def: %R8D
-; CHECK-NEXT:    movb %dil, %r8b
+; CHECK-NEXT:    movb %dl, %r8b
 ; CHECK-NEXT:    andl $1, %r8d
 ; CHECK-NEXT:    kmovw %r8d, %k1
 ; CHECK-NEXT:    kmovw %k1, %ecx
index 77160674ab204046599ff6be48d79ea9b06a8d56..4e987d7b925050c3f36ca88fc9831c6dd2b9df07 100644 (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
 }
diff --git a/llvm/test/CodeGen/X86/xor-combine-debugloc.ll b/llvm/test/CodeGen/X86/xor-combine-debugloc.ll
new file mode 100644 (file)
index 0000000..21777c1
--- /dev/null
@@ -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)