[llvm] 8565b6f - [UpdateLLCTestChecks] Add support for isel debug output in update_llc_test_checks.py

Sebastian Neubauer via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 1 02:00:02 PST 2022


Author: Yatao Wang
Date: 2022-03-01T10:55:53+01:00
New Revision: 8565b6f9f2782b8b6757fe078c4de01b61ef9ea8

URL: https://github.com/llvm/llvm-project/commit/8565b6f9f2782b8b6757fe078c4de01b61ef9ea8
DIFF: https://github.com/llvm/llvm-project/commit/8565b6f9f2782b8b6757fe078c4de01b61ef9ea8.diff

LOG: [UpdateLLCTestChecks] Add support for isel debug output in update_llc_test_checks.py

Add a check on run lines to pick up isel options in llc commands and allow
generating check lines of isel final output other than assembly. If llc command
line contains -debug-only=isel, update_llc_test_checks.py will try to scrub isel
output, otherwise, the script will fall back on default behaviour, which is try to
scrub assembly output instead.

The motivation of this change is to allow usage of update_llc_test_checks.py to
autogenerate checks of instruction selection results. In this way, we can detect
errors at an earlier stage before the compilation goes all the way to assembly.
It is an example of having some transparency for the stages between IR and
assembly. These generated tests are almost like "unit tests" of isel stage.

This patch only implements the initial change to differentiate isel output from
assembly output for Lanai. Other targets will not be supported for isel check
generation at the moment. Although adding support for it will only require
implementing the function regex and scrubber for corresponding targets.

The Lanai implementation was chosen mainly for the simplicity of demonstrating
the difference between isel checks and asm checks.

This patch also do not include the implementation of function prefix, which is
required for the generated isel checks to pass. I will put up a follow up revision
for the function prefix change to complete isel support.

Reviewed By: Flakebi

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

Added: 
    llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/amdgpu_asm.ll
    llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/amdgpu_asm.ll.expected
    llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/amdgpu_isel.ll
    llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/amdgpu_isel.ll.expected
    llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/lanai_asm.ll
    llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/lanai_asm.ll.expected
    llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/lanai_isel.ll
    llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/lanai_isel.ll.expected
    llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/x86_asm.ll
    llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/x86_asm.ll.expected
    llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/x86_isel.ll
    llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/x86_isel.ll.expected
    llvm/test/tools/UpdateTestChecks/update_llc_test_checks/amdgpu-isel-support.test
    llvm/test/tools/UpdateTestChecks/update_llc_test_checks/lanai-isel-support.test
    llvm/test/tools/UpdateTestChecks/update_llc_test_checks/x86-isel-support.test
    llvm/utils/UpdateTestChecks/isel.py

Modified: 
    llvm/utils/UpdateTestChecks/asm.py
    llvm/utils/UpdateTestChecks/common.py
    llvm/utils/update_cc_test_checks.py
    llvm/utils/update_llc_test_checks.py

Removed: 
    


################################################################################
diff  --git a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/amdgpu_asm.ll b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/amdgpu_asm.ll
new file mode 100644
index 0000000000000..850036eb27552
--- /dev/null
+++ b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/amdgpu_asm.ll
@@ -0,0 +1,32 @@
+; RUN: llc -mtriple=amdgcn-amd-amdhsa < %s | FileCheck %s
+
+define i64 @i64_test(i64 %i) nounwind readnone {
+  %loc = alloca i64
+  %j = load i64, i64 * %loc
+  %r = add i64 %i, %j
+  ret i64 %r
+}
+
+define i64 @i32_test(i32 %i) nounwind readnone {
+  %loc = alloca i32
+  %j = load i32, i32 * %loc
+  %r = add i32 %i, %j
+  %ext = zext i32 %r to i64
+  ret i64 %ext
+}
+
+define i64 @i16_test(i16 %i) nounwind readnone {
+  %loc = alloca i16
+  %j = load i16, i16 * %loc
+  %r = add i16 %i, %j
+  %ext = zext i16 %r to i64
+  ret i64 %ext
+}
+
+define i64 @i8_test(i8 %i) nounwind readnone {
+  %loc = alloca i8
+  %j = load i8, i8 * %loc
+  %r = add i8 %i, %j
+  %ext = zext i8 %r to i64
+  ret i64 %ext
+}

diff  --git a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/amdgpu_asm.ll.expected b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/amdgpu_asm.ll.expected
new file mode 100644
index 0000000000000..990ec36d2dd6d
--- /dev/null
+++ b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/amdgpu_asm.ll.expected
@@ -0,0 +1,56 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=amdgcn-amd-amdhsa < %s | FileCheck %s
+
+define i64 @i64_test(i64 %i) nounwind readnone {
+; CHECK-LABEL: i64_test:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    v_mov_b32_e32 v1, 0
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %loc = alloca i64
+  %j = load i64, i64 * %loc
+  %r = add i64 %i, %j
+  ret i64 %r
+}
+
+define i64 @i32_test(i32 %i) nounwind readnone {
+; CHECK-LABEL: i32_test:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    v_mov_b32_e32 v0, 0
+; CHECK-NEXT:    v_mov_b32_e32 v1, 0
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %loc = alloca i32
+  %j = load i32, i32 * %loc
+  %r = add i32 %i, %j
+  %ext = zext i32 %r to i64
+  ret i64 %ext
+}
+
+define i64 @i16_test(i16 %i) nounwind readnone {
+; CHECK-LABEL: i16_test:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    v_mov_b32_e32 v0, 0
+; CHECK-NEXT:    v_mov_b32_e32 v1, 0
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %loc = alloca i16
+  %j = load i16, i16 * %loc
+  %r = add i16 %i, %j
+  %ext = zext i16 %r to i64
+  ret i64 %ext
+}
+
+define i64 @i8_test(i8 %i) nounwind readnone {
+; CHECK-LABEL: i8_test:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    v_mov_b32_e32 v0, 0
+; CHECK-NEXT:    v_mov_b32_e32 v1, 0
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+  %loc = alloca i8
+  %j = load i8, i8 * %loc
+  %r = add i8 %i, %j
+  %ext = zext i8 %r to i64
+  ret i64 %ext
+}

diff  --git a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/amdgpu_isel.ll b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/amdgpu_isel.ll
new file mode 100644
index 0000000000000..1d8db1ecbc362
--- /dev/null
+++ b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/amdgpu_isel.ll
@@ -0,0 +1,32 @@
+; RUN: llc -mtriple=amdgcn-amd-amdhsa -stop-after=finalize-isel -debug-only=isel -o /dev/null %s 2>&1 | FileCheck %s
+
+define i64 @i64_test(i64 %i) nounwind readnone {
+  %loc = alloca i64
+  %j = load i64, i64 * %loc
+  %r = add i64 %i, %j
+  ret i64 %r
+}
+
+define i64 @i32_test(i32 %i) nounwind readnone {
+  %loc = alloca i32
+  %j = load i32, i32 * %loc
+  %r = add i32 %i, %j
+  %ext = zext i32 %r to i64
+  ret i64 %ext
+}
+
+define i64 @i16_test(i16 %i) nounwind readnone {
+  %loc = alloca i16
+  %j = load i16, i16 * %loc
+  %r = add i16 %i, %j
+  %ext = zext i16 %r to i64
+  ret i64 %ext
+}
+
+define i64 @i8_test(i8 %i) nounwind readnone {
+  %loc = alloca i8
+  %j = load i8, i8 * %loc
+  %r = add i8 %i, %j
+  %ext = zext i8 %r to i64
+  ret i64 %ext
+}

diff  --git a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/amdgpu_isel.ll.expected b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/amdgpu_isel.ll.expected
new file mode 100644
index 0000000000000..6d78d97884fb5
--- /dev/null
+++ b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/amdgpu_isel.ll.expected
@@ -0,0 +1,73 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=amdgcn-amd-amdhsa -stop-after=finalize-isel -debug-only=isel -o /dev/null %s 2>&1 | FileCheck %s
+
+define i64 @i64_test(i64 %i) nounwind readnone {
+; CHECK-LABEL: i64_test:
+; CHECK:       SelectionDAG has 13 nodes:
+; CHECK-NEXT:    t0: ch = EntryToken
+; CHECK-NEXT:    t11: i64,ch = CopyFromReg t0, Register:i64 %2
+; CHECK-NEXT:    t13: ch,glue = CopyToReg t0, Register:i64 %3, t11
+; CHECK-NEXT:    t15: ch,glue = CopyToReg t13, Register:i32 $vgpr0, IMPLICIT_DEF:i32, t13:1
+; CHECK-NEXT:    t21: i32 = V_MOV_B32_e32 TargetConstant:i32<0>
+; CHECK-NEXT:    t17: ch,glue = CopyToReg t15, Register:i32 $vgpr1, t21, t15:1
+; CHECK-NEXT:    t18: ch = S_SETPC_B64_return Register:i64 %3, Register:i32 $vgpr0, Register:i32 $vgpr1, t17, t17:1
+; CHECK-EMPTY:
+  %loc = alloca i64
+  %j = load i64, i64 * %loc
+  %r = add i64 %i, %j
+  ret i64 %r
+}
+
+define i64 @i32_test(i32 %i) nounwind readnone {
+; CHECK-LABEL: i32_test:
+; CHECK:       SelectionDAG has 12 nodes:
+; CHECK-NEXT:    t0: ch = EntryToken
+; CHECK-NEXT:    t5: i32 = V_MOV_B32_e32 TargetConstant:i32<0>
+; CHECK-NEXT:    t7: i64,ch = CopyFromReg t0, Register:i64 %1
+; CHECK-NEXT:    t9: ch,glue = CopyToReg t0, Register:i64 %2, t7
+; CHECK-NEXT:    t11: ch,glue = CopyToReg t9, Register:i32 $vgpr0, t5, t9:1
+; CHECK-NEXT:    t13: ch,glue = CopyToReg t11, Register:i32 $vgpr1, t5, t11:1
+; CHECK-NEXT:    t14: ch = S_SETPC_B64_return Register:i64 %2, Register:i32 $vgpr0, Register:i32 $vgpr1, t13, t13:1
+; CHECK-EMPTY:
+  %loc = alloca i32
+  %j = load i32, i32 * %loc
+  %r = add i32 %i, %j
+  %ext = zext i32 %r to i64
+  ret i64 %ext
+}
+
+define i64 @i16_test(i16 %i) nounwind readnone {
+; CHECK-LABEL: i16_test:
+; CHECK:       SelectionDAG has 12 nodes:
+; CHECK-NEXT:    t0: ch = EntryToken
+; CHECK-NEXT:    t5: i32 = V_MOV_B32_e32 TargetConstant:i32<0>
+; CHECK-NEXT:    t7: i64,ch = CopyFromReg t0, Register:i64 %1
+; CHECK-NEXT:    t9: ch,glue = CopyToReg t0, Register:i64 %2, t7
+; CHECK-NEXT:    t11: ch,glue = CopyToReg t9, Register:i32 $vgpr0, t5, t9:1
+; CHECK-NEXT:    t13: ch,glue = CopyToReg t11, Register:i32 $vgpr1, t5, t11:1
+; CHECK-NEXT:    t14: ch = S_SETPC_B64_return Register:i64 %2, Register:i32 $vgpr0, Register:i32 $vgpr1, t13, t13:1
+; CHECK-EMPTY:
+  %loc = alloca i16
+  %j = load i16, i16 * %loc
+  %r = add i16 %i, %j
+  %ext = zext i16 %r to i64
+  ret i64 %ext
+}
+
+define i64 @i8_test(i8 %i) nounwind readnone {
+; CHECK-LABEL: i8_test:
+; CHECK:       SelectionDAG has 12 nodes:
+; CHECK-NEXT:    t0: ch = EntryToken
+; CHECK-NEXT:    t5: i32 = V_MOV_B32_e32 TargetConstant:i32<0>
+; CHECK-NEXT:    t7: i64,ch = CopyFromReg t0, Register:i64 %1
+; CHECK-NEXT:    t9: ch,glue = CopyToReg t0, Register:i64 %2, t7
+; CHECK-NEXT:    t11: ch,glue = CopyToReg t9, Register:i32 $vgpr0, t5, t9:1
+; CHECK-NEXT:    t13: ch,glue = CopyToReg t11, Register:i32 $vgpr1, t5, t11:1
+; CHECK-NEXT:    t14: ch = S_SETPC_B64_return Register:i64 %2, Register:i32 $vgpr0, Register:i32 $vgpr1, t13, t13:1
+; CHECK-EMPTY:
+  %loc = alloca i8
+  %j = load i8, i8 * %loc
+  %r = add i8 %i, %j
+  %ext = zext i8 %r to i64
+  ret i64 %ext
+}

diff  --git a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/lanai_asm.ll b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/lanai_asm.ll
new file mode 100644
index 0000000000000..c29e2884b829e
--- /dev/null
+++ b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/lanai_asm.ll
@@ -0,0 +1,32 @@
+; RUN: llc -mtriple=lanai < %s | FileCheck %s
+
+define i64 @i64_test(i64 %i) nounwind readnone {
+  %loc = alloca i64
+  %j = load i64, i64 * %loc
+  %r = add i64 %i, %j
+  ret i64 %r
+}
+
+define i64 @i32_test(i32 %i) nounwind readnone {
+  %loc = alloca i32
+  %j = load i32, i32 * %loc
+  %r = add i32 %i, %j
+  %ext = zext i32 %r to i64
+  ret i64 %ext
+}
+
+define i64 @i16_test(i16 %i) nounwind readnone {
+  %loc = alloca i16
+  %j = load i16, i16 * %loc
+  %r = add i16 %i, %j
+  %ext = zext i16 %r to i64
+  ret i64 %ext
+}
+
+define i64 @i8_test(i8 %i) nounwind readnone {
+  %loc = alloca i8
+  %j = load i8, i8 * %loc
+  %r = add i8 %i, %j
+  %ext = zext i8 %r to i64
+  ret i64 %ext
+}

diff  --git a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/lanai_asm.ll.expected b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/lanai_asm.ll.expected
new file mode 100644
index 0000000000000..5704f59b9a0ab
--- /dev/null
+++ b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/lanai_asm.ll.expected
@@ -0,0 +1,95 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=lanai < %s | FileCheck %s
+
+define i64 @i64_test(i64 %i) nounwind readnone {
+; CHECK-LABEL: i64_test:
+; CHECK:       ! %bb.0:
+; CHECK-NEXT:    st %fp, [--%sp]
+; CHECK-NEXT:    add %sp, 0x8, %fp
+; CHECK-NEXT:    sub %sp, 0x10, %sp
+; CHECK-NEXT:    ld 4[%fp], %r3
+; CHECK-NEXT:    ld 0[%fp], %r9
+; CHECK-NEXT:    sub %fp, 0x10, %r12
+; CHECK-NEXT:    or %r12, 0x4, %r12
+; CHECK-NEXT:    ld -16[%fp], %r13
+; CHECK-NEXT:    ld 0[%r12], %r12
+; CHECK-NEXT:    add %r9, %r13, %r13
+; CHECK-NEXT:    add %r3, %r12, %r9
+; CHECK-NEXT:    sub.f %r9, %r3, %r0
+; CHECK-NEXT:    sult %r3
+; CHECK-NEXT:    add %r13, %r3, %rv
+; CHECK-NEXT:    ld -4[%fp], %pc ! return
+; CHECK-NEXT:    add %fp, 0x0, %sp
+; CHECK-NEXT:    ld -8[%fp], %fp
+  %loc = alloca i64
+  %j = load i64, i64 * %loc
+  %r = add i64 %i, %j
+  ret i64 %r
+}
+
+define i64 @i32_test(i32 %i) nounwind readnone {
+; CHECK-LABEL: i32_test:
+; CHECK:       ! %bb.0:
+; CHECK-NEXT:    st %fp, [--%sp]
+; CHECK-NEXT:    add %sp, 0x8, %fp
+; CHECK-NEXT:    sub %sp, 0x10, %sp
+; CHECK-NEXT:    ld 0[%fp], %r3
+; CHECK-NEXT:    ld -12[%fp], %r9
+; CHECK-NEXT:    add %r3, %r9, %r9
+; CHECK-NEXT:    or %r0, 0x0, %rv
+; CHECK-NEXT:    ld -4[%fp], %pc ! return
+; CHECK-NEXT:    add %fp, 0x0, %sp
+; CHECK-NEXT:    ld -8[%fp], %fp
+  %loc = alloca i32
+  %j = load i32, i32 * %loc
+  %r = add i32 %i, %j
+  %ext = zext i32 %r to i64
+  ret i64 %ext
+}
+
+define i64 @i16_test(i16 %i) nounwind readnone {
+; CHECK-LABEL: i16_test:
+; CHECK:       ! %bb.0:
+; CHECK-NEXT:    st %fp, [--%sp]
+; CHECK-NEXT:    add %sp, 0x8, %fp
+; CHECK-NEXT:    sub %sp, 0x10, %sp
+; CHECK-NEXT:    add %fp, 0x0, %r3
+; CHECK-NEXT:    or %r3, 0x2, %r3
+; CHECK-NEXT:    uld.h 0[%r3], %r3
+; CHECK-NEXT:    uld.h -10[%fp], %r9
+; CHECK-NEXT:    add %r3, %r9, %r3
+; CHECK-NEXT:    and %r3, 0xffff, %r9
+; CHECK-NEXT:    or %r0, 0x0, %rv
+; CHECK-NEXT:    ld -4[%fp], %pc ! return
+; CHECK-NEXT:    add %fp, 0x0, %sp
+; CHECK-NEXT:    ld -8[%fp], %fp
+  %loc = alloca i16
+  %j = load i16, i16 * %loc
+  %r = add i16 %i, %j
+  %ext = zext i16 %r to i64
+  ret i64 %ext
+}
+
+define i64 @i8_test(i8 %i) nounwind readnone {
+; CHECK-LABEL: i8_test:
+; CHECK:       ! %bb.0:
+; CHECK-NEXT:    st %fp, [--%sp]
+; CHECK-NEXT:    add %sp, 0x8, %fp
+; CHECK-NEXT:    sub %sp, 0x10, %sp
+; CHECK-NEXT:    add %fp, 0x0, %r3
+; CHECK-NEXT:    or %r3, 0x3, %r3
+; CHECK-NEXT:    uld.b 0[%r3], %r3
+; CHECK-NEXT:    uld.b -9[%fp], %r9
+; CHECK-NEXT:    add %r3, %r9, %r3
+; CHECK-NEXT:    mov 0xff, %r9
+; CHECK-NEXT:    and %r3, %r9, %r9
+; CHECK-NEXT:    or %r0, 0x0, %rv
+; CHECK-NEXT:    ld -4[%fp], %pc ! return
+; CHECK-NEXT:    add %fp, 0x0, %sp
+; CHECK-NEXT:    ld -8[%fp], %fp
+  %loc = alloca i8
+  %j = load i8, i8 * %loc
+  %r = add i8 %i, %j
+  %ext = zext i8 %r to i64
+  ret i64 %ext
+}

diff  --git a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/lanai_isel.ll b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/lanai_isel.ll
new file mode 100644
index 0000000000000..ed53b366c1c37
--- /dev/null
+++ b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/lanai_isel.ll
@@ -0,0 +1,32 @@
+; RUN: llc -mtriple=lanai -stop-after=finalize-isel -debug-only=isel -o /dev/null %s 2>&1 | FileCheck %s
+
+define i64 @i64_test(i64 %i) nounwind readnone {
+  %loc = alloca i64
+  %j = load i64, i64 * %loc
+  %r = add i64 %i, %j
+  ret i64 %r
+}
+
+define i64 @i32_test(i32 %i) nounwind readnone {
+  %loc = alloca i32
+  %j = load i32, i32 * %loc
+  %r = add i32 %i, %j
+  %ext = zext i32 %r to i64
+  ret i64 %ext
+}
+
+define i64 @i16_test(i16 %i) nounwind readnone {
+  %loc = alloca i16
+  %j = load i16, i16 * %loc
+  %r = add i16 %i, %j
+  %ext = zext i16 %r to i64
+  ret i64 %ext
+}
+
+define i64 @i8_test(i8 %i) nounwind readnone {
+  %loc = alloca i8
+  %j = load i8, i8 * %loc
+  %r = add i8 %i, %j
+  %ext = zext i8 %r to i64
+  ret i64 %ext
+}

diff  --git a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/lanai_isel.ll.expected b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/lanai_isel.ll.expected
new file mode 100644
index 0000000000000..62aa8da4b721c
--- /dev/null
+++ b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/lanai_isel.ll.expected
@@ -0,0 +1,92 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=lanai -stop-after=finalize-isel -debug-only=isel -o /dev/null %s 2>&1 | FileCheck %s
+
+define i64 @i64_test(i64 %i) nounwind readnone {
+; CHECK-LABEL: i64_test:
+; CHECK:       SelectionDAG has 22 nodes:
+; CHECK-NEXT:    t0: ch = EntryToken
+; CHECK-NEXT:    t5: i32,ch = LDW_RI<Mem:(load (s32) from %fixed-stack.0)> TargetFrameIndex:i32<-2>, TargetConstant:i32<0>, TargetConstant:i32<0>, t0
+; CHECK-NEXT:    t7: i32 = ADD_I_LO TargetFrameIndex:i32<0>, TargetConstant:i32<0>
+; CHECK-NEXT:    t29: i32 = OR_I_LO t7, TargetConstant:i32<4>
+; CHECK-NEXT:    t22: i32,ch = LDW_RI<Mem:(dereferenceable load (s32) from %ir.loc + 4, basealign 8)> t29, TargetConstant:i32<0>, TargetConstant:i32<0>, t0
+; CHECK-NEXT:    t24: i32 = ADD_R t5, t22, TargetConstant:i32<0>
+; CHECK-NEXT:    t3: i32,ch = LDW_RI<Mem:(load (s32) from %fixed-stack.1, align 8)> TargetFrameIndex:i32<-1>, TargetConstant:i32<0>, TargetConstant:i32<0>, t0
+; CHECK-NEXT:    t19: i32,ch = LDW_RI<Mem:(dereferenceable load (s32) from %ir.loc, align 8)> TargetFrameIndex:i32<0>, TargetConstant:i32<0>, TargetConstant:i32<0>, t0
+; CHECK-NEXT:    t25: i32 = ADD_R t3, t19, TargetConstant:i32<0>
+; CHECK-NEXT:    t30: i32,glue = SFSUB_F_RR t24, t5
+; CHECK-NEXT:    t31: i32 = SCC TargetConstant:i32<4>, t30:1
+; CHECK-NEXT:    t28: i32 = ADD_R t25, t31, TargetConstant:i32<0>
+; CHECK-NEXT:    t15: ch,glue = CopyToReg t0, Register:i32 $rv, t28
+; CHECK-NEXT:    t17: ch,glue = CopyToReg t15, Register:i32 $r9, t24, t15:1
+; CHECK-NEXT:    t18: ch = RET Register:i32 $rv, Register:i32 $r9, t17, t17:1
+; CHECK-EMPTY:
+  %loc = alloca i64
+  %j = load i64, i64 * %loc
+  %r = add i64 %i, %j
+  ret i64 %r
+}
+
+define i64 @i32_test(i32 %i) nounwind readnone {
+; CHECK-LABEL: i32_test:
+; CHECK:       SelectionDAG has 14 nodes:
+; CHECK-NEXT:    t0: ch = EntryToken
+; CHECK-NEXT:    t21: i32,ch = CopyFromReg t0, Register:i32 $r0
+; CHECK-NEXT:    t13: ch,glue = CopyToReg t0, Register:i32 $rv, t21
+; CHECK-NEXT:    t3: i32,ch = LDW_RI<Mem:(load (s32) from %fixed-stack.0, align 8)> TargetFrameIndex:i32<-1>, TargetConstant:i32<0>, TargetConstant:i32<0>, t0
+; CHECK-NEXT:    t6: i32,ch = LDW_RI<Mem:(dereferenceable load (s32) from %ir.loc)> TargetFrameIndex:i32<0>, TargetConstant:i32<0>, TargetConstant:i32<0>, t0
+; CHECK-NEXT:    t7: i32 = ADD_R t3, t6, TargetConstant:i32<0>
+; CHECK-NEXT:    t15: ch,glue = CopyToReg t13, Register:i32 $r9, t7, t13:1
+; CHECK-NEXT:    t16: ch = RET Register:i32 $rv, Register:i32 $r9, t15, t15:1
+; CHECK-EMPTY:
+  %loc = alloca i32
+  %j = load i32, i32 * %loc
+  %r = add i32 %i, %j
+  %ext = zext i32 %r to i64
+  ret i64 %ext
+}
+
+define i64 @i16_test(i16 %i) nounwind readnone {
+; CHECK-LABEL: i16_test:
+; CHECK:       SelectionDAG has 19 nodes:
+; CHECK-NEXT:    t0: ch = EntryToken
+; CHECK-NEXT:    t33: i32,ch = CopyFromReg t0, Register:i32 $r0
+; CHECK-NEXT:    t14: ch,glue = CopyToReg t0, Register:i32 $rv, t33
+; CHECK-NEXT:    t1: i32 = ADD_I_LO TargetFrameIndex:i32<-1>, TargetConstant:i32<0>
+; CHECK-NEXT:    t21: i32 = OR_I_LO t1, TargetConstant:i32<2>
+; CHECK-NEXT:    t23: i32,ch = LDHz_RI<Mem:(load (s16) from %fixed-stack.0 + 2)> t21, TargetConstant:i32<0>, TargetConstant:i32<0>, t0
+; CHECK-NEXT:    t22: i32,ch = LDHz_RI<Mem:(dereferenceable load (s16) from %ir.loc)> TargetFrameIndex:i32<0>, TargetConstant:i32<0>, TargetConstant:i32<0>, t0
+; CHECK-NEXT:    t24: i32 = ADD_R t23, t22, TargetConstant:i32<0>
+; CHECK-NEXT:    t27: i32 = AND_I_HI t24, TargetConstant:i32<0>
+; CHECK-NEXT:    t16: ch,glue = CopyToReg t14, Register:i32 $r9, t27, t14:1
+; CHECK-NEXT:    t28: i32 = TargetConstant<65535>
+; CHECK-NEXT:    t17: ch = RET Register:i32 $rv, Register:i32 $r9, t16, t16:1
+; CHECK-EMPTY:
+  %loc = alloca i16
+  %j = load i16, i16 * %loc
+  %r = add i16 %i, %j
+  %ext = zext i16 %r to i64
+  ret i64 %ext
+}
+
+define i64 @i8_test(i8 %i) nounwind readnone {
+; CHECK-LABEL: i8_test:
+; CHECK:       SelectionDAG has 20 nodes:
+; CHECK-NEXT:    t0: ch = EntryToken
+; CHECK-NEXT:    t33: i32,ch = CopyFromReg t0, Register:i32 $r0
+; CHECK-NEXT:    t14: ch,glue = CopyToReg t0, Register:i32 $rv, t33
+; CHECK-NEXT:    t1: i32 = ADD_I_LO TargetFrameIndex:i32<-1>, TargetConstant:i32<0>
+; CHECK-NEXT:    t21: i32 = OR_I_LO t1, TargetConstant:i32<3>
+; CHECK-NEXT:    t23: i32,ch = LDBz_RI<Mem:(load (s8) from %fixed-stack.0 + 3)> t21, TargetConstant:i32<0>, TargetConstant:i32<0>, t0
+; CHECK-NEXT:    t22: i32,ch = LDBz_RI<Mem:(dereferenceable load (s8) from %ir.loc)> TargetFrameIndex:i32<0>, TargetConstant:i32<0>, TargetConstant:i32<0>, t0
+; CHECK-NEXT:    t24: i32 = ADD_R t23, t22, TargetConstant:i32<0>
+; CHECK-NEXT:    t26: i32 = SLI TargetConstant:i32<255>
+; CHECK-NEXT:    t27: i32 = AND_R t24, t26, TargetConstant:i32<0>
+; CHECK-NEXT:    t16: ch,glue = CopyToReg t14, Register:i32 $r9, t27, t14:1
+; CHECK-NEXT:    t17: ch = RET Register:i32 $rv, Register:i32 $r9, t16, t16:1
+; CHECK-EMPTY:
+  %loc = alloca i8
+  %j = load i8, i8 * %loc
+  %r = add i8 %i, %j
+  %ext = zext i8 %r to i64
+  ret i64 %ext
+}

diff  --git a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/x86_asm.ll b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/x86_asm.ll
new file mode 100644
index 0000000000000..79f0704b7e63d
--- /dev/null
+++ b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/x86_asm.ll
@@ -0,0 +1,33 @@
+; RUN: llc -mtriple=x86_64 < %s | FileCheck %s --check-prefix=PIC
+; RUN: llc -mtriple=x86_64-windows < %s | FileCheck %s --check-prefix=WIN
+
+define i64 @i64_test(i64 %i) nounwind readnone {
+  %loc = alloca i64
+  %j = load i64, i64 * %loc
+  %r = add i64 %i, %j
+  ret i64 %r
+}
+
+define i64 @i32_test(i32 %i) nounwind readnone {
+  %loc = alloca i32
+  %j = load i32, i32 * %loc
+  %r = add i32 %i, %j
+  %ext = zext i32 %r to i64
+  ret i64 %ext
+}
+
+define i64 @i16_test(i16 %i) nounwind readnone {
+  %loc = alloca i16
+  %j = load i16, i16 * %loc
+  %r = add i16 %i, %j
+  %ext = zext i16 %r to i64
+  ret i64 %ext
+}
+
+define i64 @i8_test(i8 %i) nounwind readnone {
+  %loc = alloca i8
+  %j = load i8, i8 * %loc
+  %r = add i8 %i, %j
+  %ext = zext i8 %r to i64
+  ret i64 %ext
+}

diff  --git a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/x86_asm.ll.expected b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/x86_asm.ll.expected
new file mode 100644
index 0000000000000..06b7f9cd184da
--- /dev/null
+++ b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/x86_asm.ll.expected
@@ -0,0 +1,86 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=x86_64 < %s | FileCheck %s --check-prefix=PIC
+; RUN: llc -mtriple=x86_64-windows < %s | FileCheck %s --check-prefix=WIN
+
+define i64 @i64_test(i64 %i) nounwind readnone {
+; PIC-LABEL: i64_test:
+; PIC:       # %bb.0:
+; PIC-NEXT:    movq %rdi, %rax
+; PIC-NEXT:    addq -{{[0-9]+}}(%rsp), %rax
+; PIC-NEXT:    retq
+;
+; WIN-LABEL: i64_test:
+; WIN:       # %bb.0:
+; WIN-NEXT:    pushq %rax
+; WIN-NEXT:    movq %rcx, %rax
+; WIN-NEXT:    addq (%rsp), %rax
+; WIN-NEXT:    popq %rcx
+; WIN-NEXT:    retq
+  %loc = alloca i64
+  %j = load i64, i64 * %loc
+  %r = add i64 %i, %j
+  ret i64 %r
+}
+
+define i64 @i32_test(i32 %i) nounwind readnone {
+; PIC-LABEL: i32_test:
+; PIC:       # %bb.0:
+; PIC-NEXT:    movl %edi, %eax
+; PIC-NEXT:    addl -{{[0-9]+}}(%rsp), %eax
+; PIC-NEXT:    retq
+;
+; WIN-LABEL: i32_test:
+; WIN:       # %bb.0:
+; WIN-NEXT:    pushq %rax
+; WIN-NEXT:    movl %ecx, %eax
+; WIN-NEXT:    addl {{[0-9]+}}(%rsp), %eax
+; WIN-NEXT:    popq %rcx
+; WIN-NEXT:    retq
+  %loc = alloca i32
+  %j = load i32, i32 * %loc
+  %r = add i32 %i, %j
+  %ext = zext i32 %r to i64
+  ret i64 %ext
+}
+
+define i64 @i16_test(i16 %i) nounwind readnone {
+; PIC-LABEL: i16_test:
+; PIC:       # %bb.0:
+; PIC-NEXT:    addw -{{[0-9]+}}(%rsp), %di
+; PIC-NEXT:    movzwl %di, %eax
+; PIC-NEXT:    retq
+;
+; WIN-LABEL: i16_test:
+; WIN:       # %bb.0:
+; WIN-NEXT:    pushq %rax
+; WIN-NEXT:    addw {{[0-9]+}}(%rsp), %cx
+; WIN-NEXT:    movzwl %cx, %eax
+; WIN-NEXT:    popq %rcx
+; WIN-NEXT:    retq
+  %loc = alloca i16
+  %j = load i16, i16 * %loc
+  %r = add i16 %i, %j
+  %ext = zext i16 %r to i64
+  ret i64 %ext
+}
+
+define i64 @i8_test(i8 %i) nounwind readnone {
+; PIC-LABEL: i8_test:
+; PIC:       # %bb.0:
+; PIC-NEXT:    addb -{{[0-9]+}}(%rsp), %dil
+; PIC-NEXT:    movzbl %dil, %eax
+; PIC-NEXT:    retq
+;
+; WIN-LABEL: i8_test:
+; WIN:       # %bb.0:
+; WIN-NEXT:    pushq %rax
+; WIN-NEXT:    addb {{[0-9]+}}(%rsp), %cl
+; WIN-NEXT:    movzbl %cl, %eax
+; WIN-NEXT:    popq %rcx
+; WIN-NEXT:    retq
+  %loc = alloca i8
+  %j = load i8, i8 * %loc
+  %r = add i8 %i, %j
+  %ext = zext i8 %r to i64
+  ret i64 %ext
+}

diff  --git a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/x86_isel.ll b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/x86_isel.ll
new file mode 100644
index 0000000000000..931f8f9f3368c
--- /dev/null
+++ b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/x86_isel.ll
@@ -0,0 +1,33 @@
+; RUN: llc -mtriple=x86_64 -stop-after=finalize-isel -debug-only=isel -o /dev/null %s 2>&1 | FileCheck %s --check-prefix=PIC
+; RUN: llc -mtriple=x86_64-windows -stop-after=finalize-isel -debug-only=isel -o /dev/null %s 2>&1 | FileCheck %s --check-prefix=WIN
+
+define i64 @i64_test(i64 %i) nounwind readnone {
+  %loc = alloca i64
+  %j = load i64, i64 * %loc
+  %r = add i64 %i, %j
+  ret i64 %r
+}
+
+define i64 @i32_test(i32 %i) nounwind readnone {
+  %loc = alloca i32
+  %j = load i32, i32 * %loc
+  %r = add i32 %i, %j
+  %ext = zext i32 %r to i64
+  ret i64 %ext
+}
+
+define i64 @i16_test(i16 %i) nounwind readnone {
+  %loc = alloca i16
+  %j = load i16, i16 * %loc
+  %r = add i16 %i, %j
+  %ext = zext i16 %r to i64
+  ret i64 %ext
+}
+
+define i64 @i8_test(i8 %i) nounwind readnone {
+  %loc = alloca i8
+  %j = load i8, i8 * %loc
+  %r = add i8 %i, %j
+  %ext = zext i8 %r to i64
+  ret i64 %ext
+}

diff  --git a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/x86_isel.ll.expected b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/x86_isel.ll.expected
new file mode 100644
index 0000000000000..279c8ee2336eb
--- /dev/null
+++ b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/x86_isel.ll.expected
@@ -0,0 +1,114 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=x86_64 -stop-after=finalize-isel -debug-only=isel -o /dev/null %s 2>&1 | FileCheck %s --check-prefix=PIC
+; RUN: llc -mtriple=x86_64-windows -stop-after=finalize-isel -debug-only=isel -o /dev/null %s 2>&1 | FileCheck %s --check-prefix=WIN
+
+define i64 @i64_test(i64 %i) nounwind readnone {
+; PIC-LABEL: i64_test:
+; PIC:       SelectionDAG has 12 nodes:
+; PIC-NEXT:    t0: ch = EntryToken
+; PIC-NEXT:    t2: i64,ch = CopyFromReg t0, Register:i64 %0
+; PIC-NEXT:    t7: i64,i32,ch = ADD64rm<Mem:(dereferenceable load (s64) from %ir.loc)> t2, TargetFrameIndex:i64<0>, TargetConstant:i8<1>, Register:i64 $noreg, TargetConstant:i32<0>, Register:i16 $noreg, t0
+; PIC-NEXT:    t10: ch,glue = CopyToReg t0, Register:i64 $rax, t7
+; PIC-NEXT:    t11: ch = RET TargetConstant:i32<0>, Register:i64 $rax, t10, t10:1
+; PIC-EMPTY:
+;
+; WIN-LABEL: i64_test:
+; WIN:       SelectionDAG has 12 nodes:
+; WIN-NEXT:    t0: ch = EntryToken
+; WIN-NEXT:    t2: i64,ch = CopyFromReg t0, Register:i64 %0
+; WIN-NEXT:    t7: i64,i32,ch = ADD64rm<Mem:(dereferenceable load (s64) from %ir.loc)> t2, TargetFrameIndex:i64<0>, TargetConstant:i8<1>, Register:i64 $noreg, TargetConstant:i32<0>, Register:i16 $noreg, t0
+; WIN-NEXT:    t10: ch,glue = CopyToReg t0, Register:i64 $rax, t7
+; WIN-NEXT:    t11: ch = RET TargetConstant:i32<0>, Register:i64 $rax, t10, t10:1
+; WIN-EMPTY:
+  %loc = alloca i64
+  %j = load i64, i64 * %loc
+  %r = add i64 %i, %j
+  ret i64 %r
+}
+
+define i64 @i32_test(i32 %i) nounwind readnone {
+; PIC-LABEL: i32_test:
+; PIC:       SelectionDAG has 15 nodes:
+; PIC-NEXT:    t0: ch = EntryToken
+; PIC-NEXT:    t2: i32,ch = CopyFromReg t0, Register:i32 %0
+; PIC-NEXT:    t7: i32,i32,ch = ADD32rm<Mem:(dereferenceable load (s32) from %ir.loc)> t2, TargetFrameIndex:i64<0>, TargetConstant:i8<1>, Register:i64 $noreg, TargetConstant:i32<0>, Register:i16 $noreg, t0
+; PIC-NEXT:    t8: i64 = SUBREG_TO_REG TargetConstant:i64<0>, t7, TargetConstant:i32<6>
+; PIC-NEXT:    t11: ch,glue = CopyToReg t0, Register:i64 $rax, t8
+; PIC-NEXT:    t12: ch = RET TargetConstant:i32<0>, Register:i64 $rax, t11, t11:1
+; PIC-EMPTY:
+;
+; WIN-LABEL: i32_test:
+; WIN:       SelectionDAG has 15 nodes:
+; WIN-NEXT:    t0: ch = EntryToken
+; WIN-NEXT:    t2: i32,ch = CopyFromReg t0, Register:i32 %0
+; WIN-NEXT:    t7: i32,i32,ch = ADD32rm<Mem:(dereferenceable load (s32) from %ir.loc)> t2, TargetFrameIndex:i64<0>, TargetConstant:i8<1>, Register:i64 $noreg, TargetConstant:i32<0>, Register:i16 $noreg, t0
+; WIN-NEXT:    t8: i64 = SUBREG_TO_REG TargetConstant:i64<0>, t7, TargetConstant:i32<6>
+; WIN-NEXT:    t11: ch,glue = CopyToReg t0, Register:i64 $rax, t8
+; WIN-NEXT:    t12: ch = RET TargetConstant:i32<0>, Register:i64 $rax, t11, t11:1
+; WIN-EMPTY:
+  %loc = alloca i32
+  %j = load i32, i32 * %loc
+  %r = add i32 %i, %j
+  %ext = zext i32 %r to i64
+  ret i64 %ext
+}
+
+define i64 @i16_test(i16 %i) nounwind readnone {
+; PIC-LABEL: i16_test:
+; PIC:       SelectionDAG has 18 nodes:
+; PIC-NEXT:    t0: ch = EntryToken
+; PIC-NEXT:    t2: i32,ch = CopyFromReg t0, Register:i32 %0
+; PIC-NEXT:    t3: i16 = EXTRACT_SUBREG t2, TargetConstant:i32<4>
+; PIC-NEXT:    t8: i16,i32,ch = ADD16rm<Mem:(dereferenceable load (s16) from %ir.loc)> t3, TargetFrameIndex:i64<0>, TargetConstant:i8<1>, Register:i64 $noreg, TargetConstant:i32<0>, Register:i16 $noreg, t0
+; PIC-NEXT:    t15: i32 = MOVZX32rr16 t8
+; PIC-NEXT:    t9: i64 = SUBREG_TO_REG TargetConstant:i64<0>, t15, TargetConstant:i32<6>
+; PIC-NEXT:    t12: ch,glue = CopyToReg t0, Register:i64 $rax, t9
+; PIC-NEXT:    t13: ch = RET TargetConstant:i32<0>, Register:i64 $rax, t12, t12:1
+; PIC-EMPTY:
+;
+; WIN-LABEL: i16_test:
+; WIN:       SelectionDAG has 16 nodes:
+; WIN-NEXT:    t0: ch = EntryToken
+; WIN-NEXT:    t2: i16,ch = CopyFromReg t0, Register:i16 %0
+; WIN-NEXT:    t7: i16,i32,ch = ADD16rm<Mem:(dereferenceable load (s16) from %ir.loc)> t2, TargetFrameIndex:i64<0>, TargetConstant:i8<1>, Register:i64 $noreg, TargetConstant:i32<0>, Register:i16 $noreg, t0
+; WIN-NEXT:    t14: i32 = MOVZX32rr16 t7
+; WIN-NEXT:    t8: i64 = SUBREG_TO_REG TargetConstant:i64<0>, t14, TargetConstant:i32<6>
+; WIN-NEXT:    t11: ch,glue = CopyToReg t0, Register:i64 $rax, t8
+; WIN-NEXT:    t12: ch = RET TargetConstant:i32<0>, Register:i64 $rax, t11, t11:1
+; WIN-EMPTY:
+  %loc = alloca i16
+  %j = load i16, i16 * %loc
+  %r = add i16 %i, %j
+  %ext = zext i16 %r to i64
+  ret i64 %ext
+}
+
+define i64 @i8_test(i8 %i) nounwind readnone {
+; PIC-LABEL: i8_test:
+; PIC:       SelectionDAG has 18 nodes:
+; PIC-NEXT:    t0: ch = EntryToken
+; PIC-NEXT:    t2: i32,ch = CopyFromReg t0, Register:i32 %0
+; PIC-NEXT:    t3: i8 = EXTRACT_SUBREG t2, TargetConstant:i32<1>
+; PIC-NEXT:    t8: i8,i32,ch = ADD8rm<Mem:(dereferenceable load (s8) from %ir.loc)> t3, TargetFrameIndex:i64<0>, TargetConstant:i8<1>, Register:i64 $noreg, TargetConstant:i32<0>, Register:i16 $noreg, t0
+; PIC-NEXT:    t15: i32 = MOVZX32rr8 t8
+; PIC-NEXT:    t9: i64 = SUBREG_TO_REG TargetConstant:i64<0>, t15, TargetConstant:i32<6>
+; PIC-NEXT:    t12: ch,glue = CopyToReg t0, Register:i64 $rax, t9
+; PIC-NEXT:    t13: ch = RET TargetConstant:i32<0>, Register:i64 $rax, t12, t12:1
+; PIC-EMPTY:
+;
+; WIN-LABEL: i8_test:
+; WIN:       SelectionDAG has 16 nodes:
+; WIN-NEXT:    t0: ch = EntryToken
+; WIN-NEXT:    t2: i8,ch = CopyFromReg t0, Register:i8 %0
+; WIN-NEXT:    t7: i8,i32,ch = ADD8rm<Mem:(dereferenceable load (s8) from %ir.loc)> t2, TargetFrameIndex:i64<0>, TargetConstant:i8<1>, Register:i64 $noreg, TargetConstant:i32<0>, Register:i16 $noreg, t0
+; WIN-NEXT:    t14: i32 = MOVZX32rr8 t7
+; WIN-NEXT:    t8: i64 = SUBREG_TO_REG TargetConstant:i64<0>, t14, TargetConstant:i32<6>
+; WIN-NEXT:    t11: ch,glue = CopyToReg t0, Register:i64 $rax, t8
+; WIN-NEXT:    t12: ch = RET TargetConstant:i32<0>, Register:i64 $rax, t11, t11:1
+; WIN-EMPTY:
+  %loc = alloca i8
+  %j = load i8, i8 * %loc
+  %r = add i8 %i, %j
+  %ext = zext i8 %r to i64
+  ret i64 %ext
+}

diff  --git a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/amdgpu-isel-support.test b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/amdgpu-isel-support.test
new file mode 100644
index 0000000000000..3a531a6674b0e
--- /dev/null
+++ b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/amdgpu-isel-support.test
@@ -0,0 +1,10 @@
+# REQUIRES: amdgpu-registered-target
+## Basic test checking that update_llc_test_checks.py can update a file with isel debug output
+
+# RUN: cp -f %S/Inputs/amdgpu_isel.ll %t.ll && %update_llc_test_checks %t.ll
+# RUN: cat %S/Inputs/amdgpu_isel.ll.expected > %t.expected.ll
+# RUN: 
diff  -u %t.expected.ll %t.ll
+
+# RUN: cp -f %S/Inputs/amdgpu_asm.ll %t.ll && %update_llc_test_checks %t.ll
+# RUN: cat %S/Inputs/amdgpu_asm.ll.expected > %t.expected.ll
+# RUN: 
diff  -u %t.expected.ll %t.ll

diff  --git a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/lanai-isel-support.test b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/lanai-isel-support.test
new file mode 100644
index 0000000000000..ec5341e594e46
--- /dev/null
+++ b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/lanai-isel-support.test
@@ -0,0 +1,10 @@
+# REQUIRES: lanai-registered-target
+## Basic test checking that update_llc_test_checks.py can update a file with isel debug output
+
+# RUN: cp -f %S/Inputs/lanai_isel.ll %t.ll && %update_llc_test_checks %t.ll
+# RUN: cat %S/Inputs/lanai_isel.ll.expected > %t.expected.ll
+# RUN: 
diff  -u %t.expected.ll %t.ll
+
+# RUN: cp -f %S/Inputs/lanai_asm.ll %t.ll && %update_llc_test_checks %t.ll
+# RUN: cat %S/Inputs/lanai_asm.ll.expected > %t.expected.ll
+# RUN: 
diff  -u %t.expected.ll %t.ll

diff  --git a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/x86-isel-support.test b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/x86-isel-support.test
new file mode 100644
index 0000000000000..b02c3235d9264
--- /dev/null
+++ b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/x86-isel-support.test
@@ -0,0 +1,10 @@
+# REQUIRES: x86-registered-target
+## Basic test checking that update_llc_test_checks.py can update a file with isel debug output
+
+# RUN: cp -f %S/Inputs/x86_isel.ll %t.ll && %update_llc_test_checks %t.ll
+# RUN: cat %S/Inputs/x86_isel.ll.expected > %t.expected.ll
+# RUN: 
diff  -u %t.expected.ll %t.ll
+
+# RUN: cp -f %S/Inputs/x86_asm.ll %t.ll && %update_llc_test_checks %t.ll
+# RUN: cat %S/Inputs/x86_asm.ll.expected > %t.expected.ll
+# RUN: 
diff  -u %t.expected.ll %t.ll

diff  --git a/llvm/utils/UpdateTestChecks/asm.py b/llvm/utils/UpdateTestChecks/asm.py
index 95d17baa210e8..bb594846ff3e8 100644
--- a/llvm/utils/UpdateTestChecks/asm.py
+++ b/llvm/utils/UpdateTestChecks/asm.py
@@ -388,21 +388,6 @@ def scrub_asm_csky(asm, args):
   asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r'', asm)
   return asm
 
-def get_triple_from_march(march):
-  triples = {
-      'amdgcn': 'amdgcn',
-      'r600': 'r600',
-      'mips': 'mips',
-      'sparc': 'sparc',
-      'hexagon': 'hexagon',
-      've': 've',
-  }
-  for prefix, triple in triples.items():
-    if march.startswith(prefix):
-      return triple
-  print("Cannot find a triple. Assume 'x86'", file=sys.stderr)
-  return 'x86'
-
 def get_run_handler(triple):
   target_handlers = {
       'i686': (scrub_asm_x86, ASM_FUNCTION_X86_RE),
@@ -456,7 +441,7 @@ def get_run_handler(triple):
 
 ##### Generator of assembly CHECK lines
 
-def add_asm_checks(output_lines, comment_marker, prefix_list, func_dict,
+def add_checks(output_lines, comment_marker, prefix_list, func_dict,
                    func_name, is_filtered):
   # Label format is based on ASM string.
   check_label_format = '{} %s-LABEL: %s%s:'.format(comment_marker)

diff  --git a/llvm/utils/UpdateTestChecks/common.py b/llvm/utils/UpdateTestChecks/common.py
index dbcff53e838cf..3361f686187ef 100644
--- a/llvm/utils/UpdateTestChecks/common.py
+++ b/llvm/utils/UpdateTestChecks/common.py
@@ -306,6 +306,7 @@ def invoke_tool(exe, cmd_args, ir, preprocess_cmd=None, verbose=False):
 TRIPLE_IR_RE = re.compile(r'^\s*target\s+triple\s*=\s*"([^"]+)"$')
 TRIPLE_ARG_RE = re.compile(r'-mtriple[= ]([^ ]+)')
 MARCH_ARG_RE = re.compile(r'-march[= ]([^ ]+)')
+DEBUG_ONLY_ARG_RE = re.compile(r'-debug-only[= ]([^ ]+)')
 
 SCRUB_LEADING_WHITESPACE_RE = re.compile(r'^(\s+)')
 SCRUB_WHITESPACE_RE = re.compile(r'(?!^(|  \w))[ \t]+', flags=re.M)
@@ -351,6 +352,21 @@ def find_run_lines(test, lines):
     debug('  RUN: {}'.format(l))
   return run_lines
 
+def get_triple_from_march(march):
+  triples = {
+      'amdgcn': 'amdgcn',
+      'r600': 'r600',
+      'mips': 'mips',
+      'sparc': 'sparc',
+      'hexagon': 'hexagon',
+      've': 've',
+  }
+  for prefix, triple in triples.items():
+    if march.startswith(prefix):
+      return triple
+  print("Cannot find a triple. Assume 'x86'", file=sys.stderr)
+  return 'x86'
+
 def apply_filters(line, filters):
   has_filter = False
   for f in filters:
@@ -390,7 +406,7 @@ def __init__(self, string, extra, args_and_sig, attrs):
     self.extrascrub = extra
     self.args_and_sig = args_and_sig
     self.attrs = attrs
-  def is_same_except_arg_names(self, extrascrub, args_and_sig, attrs, is_asm):
+  def is_same_except_arg_names(self, extrascrub, args_and_sig, attrs, is_backend):
     arg_names = set()
     def drop_arg_names(match):
         arg_names.add(match.group(variable_group_in_ir_value_match))
@@ -409,9 +425,9 @@ def repl_arg_names(match):
     ans1 = IR_VALUE_RE.sub(drop_arg_names, args_and_sig)
     if ans0 != ans1:
         return False
-    if is_asm:
+    if is_backend:
         # Check without replacements, the replacements are not applied to the
-        # body for asm checks.
+        # body for backend checks.
         return self.extrascrub == extrascrub
 
     es0 = IR_VALUE_RE.sub(repl_arg_names, self.extrascrub)
@@ -460,7 +476,7 @@ def global_var_dict(self):
   def is_filtered(self):
     return bool(self._filters)
 
-  def process_run_line(self, function_re, scrubber, raw_tool_output, prefixes, is_asm):
+  def process_run_line(self, function_re, scrubber, raw_tool_output, prefixes, is_backend):
     build_global_values_dictionary(self._global_var_dict, raw_tool_output, prefixes)
     for m in function_re.finditer(raw_tool_output):
       if not m:
@@ -528,7 +544,7 @@ def process_run_line(self, function_re, scrubber, raw_tool_output, prefixes, is_
                 scrubbed_extra,
                 args_and_sig,
                 attrs,
-                is_asm)):
+                is_backend)):
               self._func_dict[prefix][func].scrub = scrubbed_extra
               self._func_dict[prefix][func].args_and_sig = args_and_sig
               continue
@@ -766,7 +782,7 @@ def transform_line_vars(match):
   return lines
 
 
-def add_checks(output_lines, comment_marker, prefix_list, func_dict, func_name, check_label_format, is_asm, is_analyze, global_vars_seen_dict, is_filtered):
+def add_checks(output_lines, comment_marker, prefix_list, func_dict, func_name, check_label_format, is_backend, is_analyze, global_vars_seen_dict, is_filtered):
   # prefix_exclusions are prefixes we cannot use to print the function because it doesn't exist in run lines that use these prefixes as well.
   prefix_exclusions = set()
   printed_prefixes = []
@@ -801,7 +817,7 @@ def add_checks(output_lines, comment_marker, prefix_list, func_dict, func_name,
 
       # Add some space between 
diff erent check prefixes, but not after the last
       # check line (before the test code).
-      if is_asm:
+      if is_backend:
         if len(printed_prefixes) != 0:
           output_lines.append(comment_marker)
 
@@ -829,7 +845,7 @@ def add_checks(output_lines, comment_marker, prefix_list, func_dict, func_name,
         continue
 
       # For ASM output, just emit the check lines.
-      if is_asm:
+      if is_backend:
         body_start = 1
         if is_filtered:
           # For filtered output we don't add "-NEXT" so don't add extra spaces

diff  --git a/llvm/utils/UpdateTestChecks/isel.py b/llvm/utils/UpdateTestChecks/isel.py
new file mode 100644
index 0000000000000..a77800a79bffa
--- /dev/null
+++ b/llvm/utils/UpdateTestChecks/isel.py
@@ -0,0 +1,57 @@
+import re
+from . import common
+import sys
+
+if sys.version_info[0] > 2:
+  class string:
+    expandtabs = str.expandtabs
+else:
+  import string
+
+# Support of isel debug checks
+# RegEx: this is where the magic happens.
+
+##### iSel parser
+
+# TODO: add function prefix
+ISEL_FUNCTION_DEFAULT_RE = re.compile(
+     r'Selected[\s]*selection[\s]*DAG:[\s]*%bb.0[\s]*\'(?P<func>.*?):[^\']*\'*\n'
+     r'(?P<body>.*?)\n'
+     r'Total[\s]*amount[\s]*of[\s]*phi[\s]*nodes[\s]*to[\s]*update:[\s]*[0-9]+',
+     flags=(re.M | re.S))
+
+def scrub_isel_default(isel, args):
+  # Scrub runs of whitespace out of the iSel debug output, but leave the leading
+  # whitespace in place.
+  isel = common.SCRUB_WHITESPACE_RE.sub(r' ', isel)
+  # Expand the tabs used for indentation.
+  isel = string.expandtabs(isel, 2)
+  # Strip trailing whitespace.
+  isel = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r'', isel)
+  return isel
+
+def get_run_handler(triple):
+  target_handlers = {
+  }
+  handler = None
+  best_prefix = ''
+  for prefix, s in target_handlers.items():
+    if triple.startswith(prefix) and len(prefix) > len(best_prefix):
+      handler = s
+      best_prefix = prefix
+
+  if handler is None:
+    common.debug('Using default handler.')
+    handler = (scrub_isel_default, ISEL_FUNCTION_DEFAULT_RE)
+
+  return handler
+
+##### Generator of iSel CHECK lines
+
+def add_checks(output_lines, comment_marker, prefix_list, func_dict, func_name, is_filtered):
+  # Label format is based on iSel string.
+  check_label_format = '{} %s-LABEL: %s%s:'.format(comment_marker)
+  global_vars_seen_dict = {}
+  common.add_checks(output_lines, comment_marker, prefix_list, func_dict,
+                    func_name, check_label_format, True, False,
+                    global_vars_seen_dict, is_filtered = is_filtered)

diff  --git a/llvm/utils/update_cc_test_checks.py b/llvm/utils/update_cc_test_checks.py
index d9c53c38796ae..1299efd46a772 100755
--- a/llvm/utils/update_cc_test_checks.py
+++ b/llvm/utils/update_cc_test_checks.py
@@ -347,7 +347,7 @@ def check_generator(my_output_lines, prefixes, func):
                                global_vars_seen_dict,
                                is_filtered=builder.is_filtered())
         else:
-          asm.add_asm_checks(my_output_lines, '//',
+          asm.add_checks(my_output_lines, '//',
                              prefixes,
                              func_dict, func,
                              is_filtered=builder.is_filtered())

diff  --git a/llvm/utils/update_llc_test_checks.py b/llvm/utils/update_llc_test_checks.py
index cf68d2384862c..03e30c89e4df8 100755
--- a/llvm/utils/update_llc_test_checks.py
+++ b/llvm/utils/update_llc_test_checks.py
@@ -12,7 +12,7 @@
 import argparse
 import os  # Used to advertise this file's name ("autogenerated_note").
 
-from UpdateTestChecks import asm, common
+from UpdateTestChecks import common
 
 # llc is the only llc-like in the LLVM tree but downstream forks can add
 # additional ones here if they have them.
@@ -79,6 +79,12 @@ def main():
       if m:
         march_in_cmd = m.groups()[0]
 
+      m = common.DEBUG_ONLY_ARG_RE.search(llc_cmd)
+      if m and m.groups()[0] == 'isel':
+        from UpdateTestChecks import isel as output_type
+      else:
+        from UpdateTestChecks import asm as output_type
+
       common.verify_filecheck_prefixes(filecheck_cmd)
       if llc_tool not in LLC_LIKE_TOOLS:
         common.warn('Skipping non-llc RUN line: ' + l)
@@ -127,9 +133,9 @@ def main():
                                            verbose=ti.args.verbose)
       triple = triple_in_cmd or triple_in_ir
       if not triple:
-        triple = asm.get_triple_from_march(march_in_cmd)
+        triple = common.get_triple_from_march(march_in_cmd)
 
-      scrubber, function_re = asm.get_run_handler(triple)
+      scrubber, function_re = output_type.get_run_handler(triple)
       builder.process_run_line(function_re, scrubber, raw_tool_output, prefixes, True)
 
     func_dict = builder.finish_and_get_func_dict()
@@ -160,7 +166,7 @@ def main():
       common.add_checks_at_end(output_lines, run_list, builder.func_order(),
                                check_indent + ';',
                                lambda my_output_lines, prefixes, func:
-                               asm.add_asm_checks(my_output_lines,
+                               output_type.add_checks(my_output_lines,
                                                   check_indent + ';',
                                                   prefixes, func_dict, func,
                                                   is_filtered=builder.is_filtered()))
@@ -178,7 +184,7 @@ def main():
               continue
 
           # Print out the various check lines here.
-          asm.add_asm_checks(output_lines, check_indent + ';', run_list,
+          output_type.add_checks(output_lines, check_indent + ';', run_list,
                              func_dict, func_name,
                              is_filtered=builder.is_filtered())
           is_in_function_start = False


        


More information about the llvm-commits mailing list