diff --git a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_function_name.ll b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_function_name.ll new file mode 100644 --- /dev/null +++ b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_function_name.ll @@ -0,0 +1,8 @@ +; Check that we accept functions with '$' in the name. + +; RUN: llc -mtriple=loongarch32-unknown-linux < %s | FileCheck %s + +define hidden i32 @"_Z54bar$ompvariant$bar"() { +entry: + ret i32 2 +} diff --git a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_function_name.ll.expected b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_function_name.ll.expected new file mode 100644 --- /dev/null +++ b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_function_name.ll.expected @@ -0,0 +1,13 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; Check that we accept functions with '$' in the name. + +; RUN: llc -mtriple=loongarch32-unknown-linux < %s | FileCheck %s + +define hidden i32 @"_Z54bar$ompvariant$bar"() { +; CHECK-LABEL: _Z54bar$ompvariant$bar: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ori $a0, $zero, 2 +; CHECK-NEXT: jirl $zero, $ra, 0 +entry: + ret i32 2 +} diff --git a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_generated_funcs.ll b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_generated_funcs.ll new file mode 100644 --- /dev/null +++ b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_generated_funcs.ll @@ -0,0 +1,63 @@ +; RUN: llc --enable-machine-outliner --mtriple=loongarch32-unknown-linux < %s | FileCheck %s +@x = dso_local global i32 0, align 4 + +define dso_local i32 @check_boundaries() #0 { + %1 = alloca i32, align 4 + %2 = alloca i32, align 4 + %3 = alloca i32, align 4 + %4 = alloca i32, align 4 + %5 = alloca i32, align 4 + store i32 0, ptr %1, align 4 + store i32 0, ptr %2, align 4 + %6 = load i32, ptr %2, align 4 + %7 = icmp ne i32 %6, 0 + br i1 %7, label %9, label %8 + + store i32 1, ptr %2, align 4 + store i32 2, ptr %3, align 4 + store i32 3, ptr %4, align 4 + store i32 4, ptr %5, align 4 + br label %10 + + store i32 1, ptr %4, align 4 + br label %10 + + %11 = load i32, ptr %2, align 4 + %12 = icmp ne i32 %11, 0 + br i1 %12, label %14, label %13 + + store i32 1, ptr %2, align 4 + store i32 2, ptr %3, align 4 + store i32 3, ptr %4, align 4 + store i32 4, ptr %5, align 4 + br label %15 + + store i32 1, ptr %4, align 4 + br label %15 + + ret i32 0 +} + +define dso_local i32 @main() #0 { + %1 = alloca i32, align 4 + %2 = alloca i32, align 4 + %3 = alloca i32, align 4 + %4 = alloca i32, align 4 + %5 = alloca i32, align 4 + + store i32 0, ptr %1, align 4 + store i32 0, ptr @x, align 4 + store i32 1, ptr %2, align 4 + store i32 2, ptr %3, align 4 + store i32 3, ptr %4, align 4 + store i32 4, ptr %5, align 4 + store i32 1, ptr @x, align 4 + call void asm sideeffect "", "~{memory},~{dirflag},~{fpsr},~{flags}"() + store i32 1, ptr %2, align 4 + store i32 2, ptr %3, align 4 + store i32 3, ptr %4, align 4 + store i32 4, ptr %5, align 4 + ret i32 0 +} + +attributes #0 = { noredzone nounwind ssp uwtable "frame-pointer"="all" } diff --git a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_generated_funcs.ll.generated.expected b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_generated_funcs.ll.generated.expected new file mode 100644 --- /dev/null +++ b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_generated_funcs.ll.generated.expected @@ -0,0 +1,148 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --include-generated-funcs +; RUN: llc --enable-machine-outliner --mtriple=loongarch32-unknown-linux < %s | FileCheck %s +@x = dso_local global i32 0, align 4 + +define dso_local i32 @check_boundaries() #0 { + %1 = alloca i32, align 4 + %2 = alloca i32, align 4 + %3 = alloca i32, align 4 + %4 = alloca i32, align 4 + %5 = alloca i32, align 4 + store i32 0, ptr %1, align 4 + store i32 0, ptr %2, align 4 + %6 = load i32, ptr %2, align 4 + %7 = icmp ne i32 %6, 0 + br i1 %7, label %9, label %8 + + store i32 1, ptr %2, align 4 + store i32 2, ptr %3, align 4 + store i32 3, ptr %4, align 4 + store i32 4, ptr %5, align 4 + br label %10 + + store i32 1, ptr %4, align 4 + br label %10 + + %11 = load i32, ptr %2, align 4 + %12 = icmp ne i32 %11, 0 + br i1 %12, label %14, label %13 + + store i32 1, ptr %2, align 4 + store i32 2, ptr %3, align 4 + store i32 3, ptr %4, align 4 + store i32 4, ptr %5, align 4 + br label %15 + + store i32 1, ptr %4, align 4 + br label %15 + + ret i32 0 +} + +define dso_local i32 @main() #0 { + %1 = alloca i32, align 4 + %2 = alloca i32, align 4 + %3 = alloca i32, align 4 + %4 = alloca i32, align 4 + %5 = alloca i32, align 4 + + store i32 0, ptr %1, align 4 + store i32 0, ptr @x, align 4 + store i32 1, ptr %2, align 4 + store i32 2, ptr %3, align 4 + store i32 3, ptr %4, align 4 + store i32 4, ptr %5, align 4 + store i32 1, ptr @x, align 4 + call void asm sideeffect "", "~{memory},~{dirflag},~{fpsr},~{flags}"() + store i32 1, ptr %2, align 4 + store i32 2, ptr %3, align 4 + store i32 3, ptr %4, align 4 + store i32 4, ptr %5, align 4 + ret i32 0 +} + +attributes #0 = { noredzone nounwind ssp uwtable "frame-pointer"="all" } +; CHECK-LABEL: check_boundaries: +; CHECK: # %bb.0: +; CHECK-NEXT: addi.w $sp, $sp, -32 +; CHECK-NEXT: .cfi_def_cfa_offset 32 +; CHECK-NEXT: st.w $ra, $sp, 28 # 4-byte Folded Spill +; CHECK-NEXT: st.w $fp, $sp, 24 # 4-byte Folded Spill +; CHECK-NEXT: .cfi_offset 1, -4 +; CHECK-NEXT: .cfi_offset 22, -8 +; CHECK-NEXT: addi.w $fp, $sp, 32 +; CHECK-NEXT: .cfi_def_cfa 22, 0 +; CHECK-NEXT: st.w $zero, $fp, -16 +; CHECK-NEXT: st.w $zero, $fp, -12 +; CHECK-NEXT: bnez $zero, .LBB0_2 +; CHECK-NEXT: b .LBB0_1 +; CHECK-NEXT: .LBB0_2: +; CHECK-NEXT: ori $a0, $zero, 1 +; CHECK-NEXT: st.w $a0, $fp, -24 +; CHECK-NEXT: .LBB0_3: +; CHECK-NEXT: ld.w $a0, $fp, -16 +; CHECK-NEXT: bne $a0, $zero, .LBB0_5 +; CHECK-NEXT: b .LBB0_4 +; CHECK-NEXT: .LBB0_5: +; CHECK-NEXT: ori $a0, $zero, 1 +; CHECK-NEXT: st.w $a0, $fp, -24 +; CHECK-NEXT: .LBB0_6: +; CHECK-NEXT: move $a0, $zero +; CHECK-NEXT: ld.w $fp, $sp, 24 # 4-byte Folded Reload +; CHECK-NEXT: ld.w $ra, $sp, 28 # 4-byte Folded Reload +; CHECK-NEXT: addi.w $sp, $sp, 32 +; CHECK-NEXT: jirl $zero, $ra, 0 +; CHECK-NEXT: .LBB0_1: +; CHECK-NEXT: ori $a0, $zero, 2 +; CHECK-NEXT: st.w $a0, $fp, -20 +; CHECK-NEXT: ori $a0, $zero, 1 +; CHECK-NEXT: st.w $a0, $fp, -16 +; CHECK-NEXT: ori $a0, $zero, 3 +; CHECK-NEXT: st.w $a0, $fp, -24 +; CHECK-NEXT: ori $a0, $zero, 4 +; CHECK-NEXT: st.w $a0, $fp, -28 +; CHECK-NEXT: b .LBB0_3 +; CHECK-NEXT: .LBB0_4: +; CHECK-NEXT: ori $a0, $zero, 2 +; CHECK-NEXT: st.w $a0, $fp, -20 +; CHECK-NEXT: ori $a0, $zero, 1 +; CHECK-NEXT: st.w $a0, $fp, -16 +; CHECK-NEXT: ori $a0, $zero, 3 +; CHECK-NEXT: st.w $a0, $fp, -24 +; CHECK-NEXT: ori $a0, $zero, 4 +; CHECK-NEXT: st.w $a0, $fp, -28 +; CHECK-NEXT: b .LBB0_6 +; +; CHECK-LABEL: main: +; CHECK: # %bb.0: +; CHECK-NEXT: addi.w $sp, $sp, -32 +; CHECK-NEXT: .cfi_def_cfa_offset 32 +; CHECK-NEXT: st.w $ra, $sp, 28 # 4-byte Folded Spill +; CHECK-NEXT: st.w $fp, $sp, 24 # 4-byte Folded Spill +; CHECK-NEXT: .cfi_offset 1, -4 +; CHECK-NEXT: .cfi_offset 22, -8 +; CHECK-NEXT: addi.w $fp, $sp, 32 +; CHECK-NEXT: .cfi_def_cfa 22, 0 +; CHECK-NEXT: pcalau12i $a0, x +; CHECK-NEXT: addi.w $a0, $a0, x +; CHECK-NEXT: ori $a1, $zero, 1 +; CHECK-NEXT: st.w $a1, $a0, 0 +; CHECK-NEXT: st.w $zero, $fp, -12 +; CHECK-NEXT: st.w $a1, $fp, -16 +; CHECK-NEXT: ori $a0, $zero, 2 +; CHECK-NEXT: st.w $a0, $fp, -20 +; CHECK-NEXT: ori $a2, $zero, 3 +; CHECK-NEXT: st.w $a2, $fp, -24 +; CHECK-NEXT: ori $a3, $zero, 4 +; CHECK-NEXT: st.w $a3, $fp, -28 +; CHECK-NEXT: #APP +; CHECK-NEXT: #NO_APP +; CHECK-NEXT: st.w $a0, $fp, -20 +; CHECK-NEXT: st.w $a1, $fp, -16 +; CHECK-NEXT: st.w $a2, $fp, -24 +; CHECK-NEXT: st.w $a3, $fp, -28 +; CHECK-NEXT: move $a0, $zero +; CHECK-NEXT: ld.w $fp, $sp, 24 # 4-byte Folded Reload +; CHECK-NEXT: ld.w $ra, $sp, 28 # 4-byte Folded Reload +; CHECK-NEXT: addi.w $sp, $sp, 32 +; CHECK-NEXT: jirl $zero, $ra, 0 diff --git a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_generated_funcs.ll.nogenerated.expected b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_generated_funcs.ll.nogenerated.expected new file mode 100644 --- /dev/null +++ b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_generated_funcs.ll.nogenerated.expected @@ -0,0 +1,147 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc --enable-machine-outliner --mtriple=loongarch32-unknown-linux < %s | FileCheck %s +@x = dso_local global i32 0, align 4 + +define dso_local i32 @check_boundaries() #0 { +; CHECK-LABEL: check_boundaries: +; CHECK: # %bb.0: +; CHECK-NEXT: addi.w $sp, $sp, -32 +; CHECK-NEXT: .cfi_def_cfa_offset 32 +; CHECK-NEXT: st.w $ra, $sp, 28 # 4-byte Folded Spill +; CHECK-NEXT: st.w $fp, $sp, 24 # 4-byte Folded Spill +; CHECK-NEXT: .cfi_offset 1, -4 +; CHECK-NEXT: .cfi_offset 22, -8 +; CHECK-NEXT: addi.w $fp, $sp, 32 +; CHECK-NEXT: .cfi_def_cfa 22, 0 +; CHECK-NEXT: st.w $zero, $fp, -16 +; CHECK-NEXT: st.w $zero, $fp, -12 +; CHECK-NEXT: bnez $zero, .LBB0_2 +; CHECK-NEXT: b .LBB0_1 +; CHECK-NEXT: .LBB0_2: +; CHECK-NEXT: ori $a0, $zero, 1 +; CHECK-NEXT: st.w $a0, $fp, -24 +; CHECK-NEXT: .LBB0_3: +; CHECK-NEXT: ld.w $a0, $fp, -16 +; CHECK-NEXT: bne $a0, $zero, .LBB0_5 +; CHECK-NEXT: b .LBB0_4 +; CHECK-NEXT: .LBB0_5: +; CHECK-NEXT: ori $a0, $zero, 1 +; CHECK-NEXT: st.w $a0, $fp, -24 +; CHECK-NEXT: .LBB0_6: +; CHECK-NEXT: move $a0, $zero +; CHECK-NEXT: ld.w $fp, $sp, 24 # 4-byte Folded Reload +; CHECK-NEXT: ld.w $ra, $sp, 28 # 4-byte Folded Reload +; CHECK-NEXT: addi.w $sp, $sp, 32 +; CHECK-NEXT: jirl $zero, $ra, 0 +; CHECK-NEXT: .LBB0_1: +; CHECK-NEXT: ori $a0, $zero, 2 +; CHECK-NEXT: st.w $a0, $fp, -20 +; CHECK-NEXT: ori $a0, $zero, 1 +; CHECK-NEXT: st.w $a0, $fp, -16 +; CHECK-NEXT: ori $a0, $zero, 3 +; CHECK-NEXT: st.w $a0, $fp, -24 +; CHECK-NEXT: ori $a0, $zero, 4 +; CHECK-NEXT: st.w $a0, $fp, -28 +; CHECK-NEXT: b .LBB0_3 +; CHECK-NEXT: .LBB0_4: +; CHECK-NEXT: ori $a0, $zero, 2 +; CHECK-NEXT: st.w $a0, $fp, -20 +; CHECK-NEXT: ori $a0, $zero, 1 +; CHECK-NEXT: st.w $a0, $fp, -16 +; CHECK-NEXT: ori $a0, $zero, 3 +; CHECK-NEXT: st.w $a0, $fp, -24 +; CHECK-NEXT: ori $a0, $zero, 4 +; CHECK-NEXT: st.w $a0, $fp, -28 +; CHECK-NEXT: b .LBB0_6 + %1 = alloca i32, align 4 + %2 = alloca i32, align 4 + %3 = alloca i32, align 4 + %4 = alloca i32, align 4 + %5 = alloca i32, align 4 + store i32 0, ptr %1, align 4 + store i32 0, ptr %2, align 4 + %6 = load i32, ptr %2, align 4 + %7 = icmp ne i32 %6, 0 + br i1 %7, label %9, label %8 + + store i32 1, ptr %2, align 4 + store i32 2, ptr %3, align 4 + store i32 3, ptr %4, align 4 + store i32 4, ptr %5, align 4 + br label %10 + + store i32 1, ptr %4, align 4 + br label %10 + + %11 = load i32, ptr %2, align 4 + %12 = icmp ne i32 %11, 0 + br i1 %12, label %14, label %13 + + store i32 1, ptr %2, align 4 + store i32 2, ptr %3, align 4 + store i32 3, ptr %4, align 4 + store i32 4, ptr %5, align 4 + br label %15 + + store i32 1, ptr %4, align 4 + br label %15 + + ret i32 0 +} + +define dso_local i32 @main() #0 { +; CHECK-LABEL: main: +; CHECK: # %bb.0: +; CHECK-NEXT: addi.w $sp, $sp, -32 +; CHECK-NEXT: .cfi_def_cfa_offset 32 +; CHECK-NEXT: st.w $ra, $sp, 28 # 4-byte Folded Spill +; CHECK-NEXT: st.w $fp, $sp, 24 # 4-byte Folded Spill +; CHECK-NEXT: .cfi_offset 1, -4 +; CHECK-NEXT: .cfi_offset 22, -8 +; CHECK-NEXT: addi.w $fp, $sp, 32 +; CHECK-NEXT: .cfi_def_cfa 22, 0 +; CHECK-NEXT: pcalau12i $a0, x +; CHECK-NEXT: addi.w $a0, $a0, x +; CHECK-NEXT: ori $a1, $zero, 1 +; CHECK-NEXT: st.w $a1, $a0, 0 +; CHECK-NEXT: st.w $zero, $fp, -12 +; CHECK-NEXT: st.w $a1, $fp, -16 +; CHECK-NEXT: ori $a0, $zero, 2 +; CHECK-NEXT: st.w $a0, $fp, -20 +; CHECK-NEXT: ori $a2, $zero, 3 +; CHECK-NEXT: st.w $a2, $fp, -24 +; CHECK-NEXT: ori $a3, $zero, 4 +; CHECK-NEXT: st.w $a3, $fp, -28 +; CHECK-NEXT: #APP +; CHECK-NEXT: #NO_APP +; CHECK-NEXT: st.w $a0, $fp, -20 +; CHECK-NEXT: st.w $a1, $fp, -16 +; CHECK-NEXT: st.w $a2, $fp, -24 +; CHECK-NEXT: st.w $a3, $fp, -28 +; CHECK-NEXT: move $a0, $zero +; CHECK-NEXT: ld.w $fp, $sp, 24 # 4-byte Folded Reload +; CHECK-NEXT: ld.w $ra, $sp, 28 # 4-byte Folded Reload +; CHECK-NEXT: addi.w $sp, $sp, 32 +; CHECK-NEXT: jirl $zero, $ra, 0 + %1 = alloca i32, align 4 + %2 = alloca i32, align 4 + %3 = alloca i32, align 4 + %4 = alloca i32, align 4 + %5 = alloca i32, align 4 + + store i32 0, ptr %1, align 4 + store i32 0, ptr @x, align 4 + store i32 1, ptr %2, align 4 + store i32 2, ptr %3, align 4 + store i32 3, ptr %4, align 4 + store i32 4, ptr %5, align 4 + store i32 1, ptr @x, align 4 + call void asm sideeffect "", "~{memory},~{dirflag},~{fpsr},~{flags}"() + store i32 1, ptr %2, align 4 + store i32 2, ptr %3, align 4 + store i32 3, ptr %4, align 4 + store i32 4, ptr %5, align 4 + ret i32 0 +} + +attributes #0 = { noredzone nounwind ssp uwtable "frame-pointer"="all" } diff --git a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/loongarch-function-name.test b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/loongarch-function-name.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/loongarch-function-name.test @@ -0,0 +1,5 @@ +# REQUIRES: loongarch-registered-target +## Check that functions names with '$' are processed correctly + +# RUN: cp -f %S/Inputs/loongarch_function_name.ll %t.ll && %update_llc_test_checks %t.ll +# RUN: diff -u %S/Inputs/loongarch_function_name.ll.expected %t.ll diff --git a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/loongarch_generated_funcs.test b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/loongarch_generated_funcs.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/loongarch_generated_funcs.test @@ -0,0 +1,17 @@ +# REQUIRES: loongarch-registered-target + +## Check that generated functions are included. +# RUN: cp -f %S/Inputs/loongarch_generated_funcs.ll %t.ll && %update_llc_test_checks --include-generated-funcs %t.ll +# RUN: diff -u %t.ll %S/Inputs/loongarch_generated_funcs.ll.generated.expected + +## Check that running the script again does not change the result: +# RUN: %update_llc_test_checks --include-generated-funcs %t.ll +# RUN: diff -u %t.ll %S/Inputs/loongarch_generated_funcs.ll.generated.expected + +## Check that generated functions are not included. +# RUN: cp -f %S/Inputs/loongarch_generated_funcs.ll %t.ll && %update_llc_test_checks %t.ll +# RUN: diff -u %t.ll %S/Inputs/loongarch_generated_funcs.ll.nogenerated.expected + +## Check that running the script again does not change the result: +# RUN: %update_llc_test_checks %t.ll +# RUN: diff -u %t.ll %S/Inputs/loongarch_generated_funcs.ll.nogenerated.expected diff --git a/llvm/utils/UpdateTestChecks/asm.py b/llvm/utils/UpdateTestChecks/asm.py --- a/llvm/utils/UpdateTestChecks/asm.py +++ b/llvm/utils/UpdateTestChecks/asm.py @@ -203,6 +203,13 @@ r'\s*// -- End function', flags=(re.M | re.S)) +ASM_FUNCTION_LOONGARCH_RE = re.compile( + r'^_?(?P[^:]+):[ \t]*#+[ \t]*@"?(?P=func)"?\n' + r'(?:\s*\.?Lfunc_begin[^:\n]*:\n)?[^:]*?' + r'(?P^##?[ \t]+[^:]+:.*?)\s*' + r'.Lfunc_end[0-9]+:\n', + flags=(re.M | re.S)) + SCRUB_X86_SHUFFLES_RE = ( re.compile( r'^(\s*\w+) [^#\n]+#+ ((?:[xyz]mm\d+|mem)( \{%k\d+\}( \{z\})?)? = .*)$', @@ -423,6 +430,16 @@ asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r'', asm) return asm +def scrub_asm_loongarch(asm, args): + # Scrub runs of whitespace out of the assembly, but leave the leading + # whitespace in place. + asm = common.SCRUB_WHITESPACE_RE.sub(r' ', asm) + # Expand the tabs used for indentation. + asm = string.expandtabs(asm, 2) + # Strip trailing whitespace. + asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r'', asm) + return asm + # Returns a tuple of a scrub function and a function regex. Scrub function is # used to alter function body in some way, for example, remove trailing spaces. # Function regex is used to match function name, body, etc. in raw llc output. @@ -464,7 +481,9 @@ 'wasm32': (scrub_asm_wasm32, ASM_FUNCTION_WASM32_RE), 've': (scrub_asm_ve, ASM_FUNCTION_VE_RE), 'csky': (scrub_asm_csky, ASM_FUNCTION_CSKY_RE), - 'nvptx': (scrub_asm_nvptx, ASM_FUNCTION_NVPTX_RE) + 'nvptx': (scrub_asm_nvptx, ASM_FUNCTION_NVPTX_RE), + 'loongarch32': (scrub_asm_loongarch, ASM_FUNCTION_LOONGARCH_RE), + 'loongarch64': (scrub_asm_loongarch, ASM_FUNCTION_LOONGARCH_RE) } handler = None best_prefix = ''