Index: llvm/test/CodeGen/PowerPC/shift_mask.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/PowerPC/shift_mask.ll @@ -0,0 +1,298 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s | FileCheck %s +target triple = "powerpc64le-linux-gnu" + +define i8 @test000(i8 %a, i8 %b) { +; CHECK-LABEL: test000: +; CHECK: # BB#0: +; CHECK-NEXT: rlwinm 4, 4, 0, 29, 31 +; CHECK-NEXT: slw 3, 3, 4 +; CHECK-NEXT: blr + %rem = and i8 %b, 7 + %shl = shl i8 %a, %rem + ret i8 %shl +} + +define i16 @test001(i16 %a, i16 %b) { +; CHECK-LABEL: test001: +; CHECK: # BB#0: +; CHECK-NEXT: rlwinm 4, 4, 0, 28, 31 +; CHECK-NEXT: slw 3, 3, 4 +; CHECK-NEXT: blr + %rem = and i16 %b, 15 + %shl = shl i16 %a, %rem + ret i16 %shl +} + +define i32 @test002(i32 %a, i32 %b) { +; CHECK-LABEL: test002: +; CHECK: # BB#0: +; CHECK-NEXT: rlwinm 4, 4, 0, 27, 31 +; CHECK-NEXT: slw 3, 3, 4 +; CHECK-NEXT: blr + %rem = and i32 %b, 31 + %shl = shl i32 %a, %rem + ret i32 %shl +} + +define i64 @test003(i64 %a, i64 %b) { +; CHECK-LABEL: test003: +; CHECK: # BB#0: +; CHECK-NEXT: rlwinm 4, 4, 0, 26, 31 +; CHECK-NEXT: sld 3, 3, 4 +; CHECK-NEXT: blr + %rem = and i64 %b, 63 + %shl = shl i64 %a, %rem + ret i64 %shl +} + +define <16 x i8> @test010(<16 x i8> %a, <16 x i8> %b) { +; CHECK-LABEL: test010: +; CHECK: # BB#0: +; CHECK-NEXT: vspltisb 4, 7 +; CHECK-NEXT: xxland 35, 35, 36 +; CHECK-NEXT: vslb 2, 2, 3 +; CHECK-NEXT: blr + %rem = and <16 x i8> %b, + %shl = shl <16 x i8> %a, %rem + ret <16 x i8> %shl +} + +define <8 x i16> @test011(<8 x i16> %a, <8 x i16> %b) { +; CHECK-LABEL: test011: +; CHECK: # BB#0: +; CHECK-NEXT: vspltish 4, 15 +; CHECK-NEXT: xxland 35, 35, 36 +; CHECK-NEXT: vslh 2, 2, 3 +; CHECK-NEXT: blr + %rem = and <8 x i16> %b, + %shl = shl <8 x i16> %a, %rem + ret <8 x i16> %shl +} + +define <4 x i32> @test012(<4 x i32> %a, <4 x i32> %b) { +; CHECK-LABEL: test012: +; CHECK: # BB#0: +; CHECK-NEXT: vspltisw 4, -16 +; CHECK-NEXT: vspltisw 5, 15 +; CHECK-NEXT: vsubuwm 4, 5, 4 +; CHECK-NEXT: xxland 35, 35, 36 +; CHECK-NEXT: vslw 2, 2, 3 +; CHECK-NEXT: blr + %rem = and <4 x i32> %b, + %shl = shl <4 x i32> %a, %rem + ret <4 x i32> %shl +} + +define <2 x i64> @test013(<2 x i64> %a, <2 x i64> %b) { +; CHECK-LABEL: test013: +; CHECK: # BB#0: +; CHECK-NEXT: addis 3, 2, .LCPI7_0@toc@ha +; CHECK-NEXT: addi 3, 3, .LCPI7_0@toc@l +; CHECK-NEXT: lxvd2x 0, 0, 3 +; CHECK-NEXT: xxswapd 36, 0 +; CHECK-NEXT: xxland 35, 35, 36 +; CHECK-NEXT: vsld 2, 2, 3 +; CHECK-NEXT: blr + %rem = and <2 x i64> %b, + %shl = shl <2 x i64> %a, %rem + ret <2 x i64> %shl +} + +define i8 @test100(i8 %a, i8 %b) { +; CHECK-LABEL: test100: +; CHECK: # BB#0: +; CHECK-NEXT: rlwinm 3, 3, 0, 24, 31 +; CHECK-NEXT: rlwinm 4, 4, 0, 29, 31 +; CHECK-NEXT: srw 3, 3, 4 +; CHECK-NEXT: blr + %rem = and i8 %b, 7 + %lshr = lshr i8 %a, %rem + ret i8 %lshr +} + +define i16 @test101(i16 %a, i16 %b) { +; CHECK-LABEL: test101: +; CHECK: # BB#0: +; CHECK-NEXT: rlwinm 3, 3, 0, 16, 31 +; CHECK-NEXT: rlwinm 4, 4, 0, 28, 31 +; CHECK-NEXT: srw 3, 3, 4 +; CHECK-NEXT: blr + %rem = and i16 %b, 15 + %lshr = lshr i16 %a, %rem + ret i16 %lshr +} + +define i32 @test102(i32 %a, i32 %b) { +; CHECK-LABEL: test102: +; CHECK: # BB#0: +; CHECK-NEXT: rlwinm 4, 4, 0, 27, 31 +; CHECK-NEXT: srw 3, 3, 4 +; CHECK-NEXT: blr + %rem = and i32 %b, 31 + %lshr = lshr i32 %a, %rem + ret i32 %lshr +} + +define i64 @test103(i64 %a, i64 %b) { +; CHECK-LABEL: test103: +; CHECK: # BB#0: +; CHECK-NEXT: rlwinm 4, 4, 0, 26, 31 +; CHECK-NEXT: srd 3, 3, 4 +; CHECK-NEXT: blr + %rem = and i64 %b, 63 + %lshr = lshr i64 %a, %rem + ret i64 %lshr +} + +define <16 x i8> @test110(<16 x i8> %a, <16 x i8> %b) { +; CHECK-LABEL: test110: +; CHECK: # BB#0: +; CHECK-NEXT: vspltisb 4, 7 +; CHECK-NEXT: xxland 35, 35, 36 +; CHECK-NEXT: vsrb 2, 2, 3 +; CHECK-NEXT: blr + %rem = and <16 x i8> %b, + %lshr = lshr <16 x i8> %a, %rem + ret <16 x i8> %lshr +} + +define <8 x i16> @test111(<8 x i16> %a, <8 x i16> %b) { +; CHECK-LABEL: test111: +; CHECK: # BB#0: +; CHECK-NEXT: vspltish 4, 15 +; CHECK-NEXT: xxland 35, 35, 36 +; CHECK-NEXT: vsrh 2, 2, 3 +; CHECK-NEXT: blr + %rem = and <8 x i16> %b, + %lshr = lshr <8 x i16> %a, %rem + ret <8 x i16> %lshr +} + +define <4 x i32> @test112(<4 x i32> %a, <4 x i32> %b) { +; CHECK-LABEL: test112: +; CHECK: # BB#0: +; CHECK-NEXT: vspltisw 4, -16 +; CHECK-NEXT: vspltisw 5, 15 +; CHECK-NEXT: vsubuwm 4, 5, 4 +; CHECK-NEXT: xxland 35, 35, 36 +; CHECK-NEXT: vsrw 2, 2, 3 +; CHECK-NEXT: blr + %rem = and <4 x i32> %b, + %lshr = lshr <4 x i32> %a, %rem + ret <4 x i32> %lshr +} + +define <2 x i64> @test113(<2 x i64> %a, <2 x i64> %b) { +; CHECK-LABEL: test113: +; CHECK: # BB#0: +; CHECK-NEXT: addis 3, 2, .LCPI15_0@toc@ha +; CHECK-NEXT: addi 3, 3, .LCPI15_0@toc@l +; CHECK-NEXT: lxvd2x 0, 0, 3 +; CHECK-NEXT: xxswapd 36, 0 +; CHECK-NEXT: xxland 35, 35, 36 +; CHECK-NEXT: vsrd 2, 2, 3 +; CHECK-NEXT: blr + %rem = and <2 x i64> %b, + %lshr = lshr <2 x i64> %a, %rem + ret <2 x i64> %lshr +} + +define i8 @test200(i8 %a, i8 %b) { +; CHECK-LABEL: test200: +; CHECK: # BB#0: +; CHECK-NEXT: extsb 3, 3 +; CHECK-NEXT: rlwinm 4, 4, 0, 29, 31 +; CHECK-NEXT: sraw 3, 3, 4 +; CHECK-NEXT: blr + %rem = and i8 %b, 7 + %ashr = ashr i8 %a, %rem + ret i8 %ashr +} + +define i16 @test201(i16 %a, i16 %b) { +; CHECK-LABEL: test201: +; CHECK: # BB#0: +; CHECK-NEXT: extsh 3, 3 +; CHECK-NEXT: rlwinm 4, 4, 0, 28, 31 +; CHECK-NEXT: sraw 3, 3, 4 +; CHECK-NEXT: blr + %rem = and i16 %b, 15 + %ashr = ashr i16 %a, %rem + ret i16 %ashr +} + +define i32 @test202(i32 %a, i32 %b) { +; CHECK-LABEL: test202: +; CHECK: # BB#0: +; CHECK-NEXT: rlwinm 4, 4, 0, 27, 31 +; CHECK-NEXT: sraw 3, 3, 4 +; CHECK-NEXT: blr + %rem = and i32 %b, 31 + %ashr = ashr i32 %a, %rem + ret i32 %ashr +} + +define i64 @test203(i64 %a, i64 %b) { +; CHECK-LABEL: test203: +; CHECK: # BB#0: +; CHECK-NEXT: rlwinm 4, 4, 0, 26, 31 +; CHECK-NEXT: srad 3, 3, 4 +; CHECK-NEXT: blr + %rem = and i64 %b, 63 + %ashr = ashr i64 %a, %rem + ret i64 %ashr +} + +define <16 x i8> @test210(<16 x i8> %a, <16 x i8> %b) { +; CHECK-LABEL: test210: +; CHECK: # BB#0: +; CHECK-NEXT: vspltisb 4, 7 +; CHECK-NEXT: xxland 35, 35, 36 +; CHECK-NEXT: vsrab 2, 2, 3 +; CHECK-NEXT: blr + %rem = and <16 x i8> %b, + %ashr = ashr <16 x i8> %a, %rem + ret <16 x i8> %ashr +} + +define <8 x i16> @test211(<8 x i16> %a, <8 x i16> %b) { +; CHECK-LABEL: test211: +; CHECK: # BB#0: +; CHECK-NEXT: vspltish 4, 15 +; CHECK-NEXT: xxland 35, 35, 36 +; CHECK-NEXT: vsrah 2, 2, 3 +; CHECK-NEXT: blr + %rem = and <8 x i16> %b, + %ashr = ashr <8 x i16> %a, %rem + ret <8 x i16> %ashr +} + +define <4 x i32> @test212(<4 x i32> %a, <4 x i32> %b) { +; CHECK-LABEL: test212: +; CHECK: # BB#0: +; CHECK-NEXT: vspltisw 4, -16 +; CHECK-NEXT: vspltisw 5, 15 +; CHECK-NEXT: vsubuwm 4, 5, 4 +; CHECK-NEXT: xxland 35, 35, 36 +; CHECK-NEXT: vsraw 2, 2, 3 +; CHECK-NEXT: blr + %rem = and <4 x i32> %b, + %ashr = ashr <4 x i32> %a, %rem + ret <4 x i32> %ashr +} + +define <2 x i64> @test213(<2 x i64> %a, <2 x i64> %b) { +; CHECK-LABEL: test213: +; CHECK: # BB#0: +; CHECK-NEXT: addis 3, 2, .LCPI23_0@toc@ha +; CHECK-NEXT: addi 3, 3, .LCPI23_0@toc@l +; CHECK-NEXT: lxvd2x 0, 0, 3 +; CHECK-NEXT: xxswapd 36, 0 +; CHECK-NEXT: xxland 35, 35, 36 +; CHECK-NEXT: vsrad 2, 2, 3 +; CHECK-NEXT: blr + %rem = and <2 x i64> %b, + %ashr = ashr <2 x i64> %a, %rem + ret <2 x i64> %ashr +} Index: llvm/utils/update_llc_test_checks.py =================================================================== --- llvm/utils/update_llc_test_checks.py +++ llvm/utils/update_llc_test_checks.py @@ -51,10 +51,23 @@ flags=(re.M | re.S)) RUN_LINE_RE = re.compile('^\s*;\s*RUN:\s*(.*)$') +TRIPLE_ARG_RE = re.compile(r'-mtriple=([^ ]+)') +TRIPLE_IR_RE = re.compile(r'^target\s+triple\s*=\s*"([^"]+)"$') IR_FUNCTION_RE = re.compile('^\s*define\s+(?:internal\s+)?[^@]*@(\w+)\s*\(') CHECK_PREFIX_RE = re.compile('--check-prefix=(\S+)') CHECK_RE = re.compile(r'^\s*;\s*([^:]+?)(?:-NEXT|-NOT|-DAG|-LABEL)?:') +ASM_FUNCTION_PPC_RE = re.compile( + r'^_?(?P[^:]+):[ \t]*#+[ \t]*@(?P=func)\n' + r'\.Lfunc_begin[0-9]+:\n' + r'[ \t]+.cfi_startproc\n' + r'(?:\.Lfunc_[gl]ep[0-9]+:\n(?:[ \t]+.*?\n)*)*' + r'(?P.*?)\n' + # This list is incomplete + r'(?:^[ \t]*(?:\.long[ \t]+[^\n]+|\.quad[ \t]+[^\n]+)\n)*' + r'.Lfunc_end[0-9]+:\n', + flags=(re.M | re.S)) + def scrub_asm_x86(asm): # Scrub runs of whitespace out of the assembly, but leave the leading @@ -76,7 +89,7 @@ asm = SCRUB_TRAILING_WHITESPACE_RE.sub(r'', asm) return asm -def scrub_asm_arm(asm): +def scrub_asm_arm_eabi(asm): # Scrub runs of whitespace out of the assembly, but leave the leading # whitespace in place. asm = SCRUB_WHITESPACE_RE.sub(r' ', asm) @@ -88,19 +101,42 @@ asm = SCRUB_TRAILING_WHITESPACE_RE.sub(r'', asm) return asm +def scrub_asm_powerpc64le(asm): + # Scrub runs of whitespace out of the assembly, but leave the leading + # whitespace in place. + asm = SCRUB_WHITESPACE_RE.sub(r' ', asm) + # Expand the tabs used for indentation. + asm = string.expandtabs(asm, 2) + # Strip trailing whitespace. + asm = SCRUB_TRAILING_WHITESPACE_RE.sub(r'', asm) + return asm + # Build up a dictionary of all the function bodies. -def build_function_body_dictionary(raw_tool_output, prefixes, func_dict, verbose): - is_arm = re.compile(r'\n\s+\.syntax unified\n').search(raw_tool_output) - function_re = ASM_FUNCTION_ARM_RE if is_arm else ASM_FUNCTION_X86_RE +def build_function_body_dictionary(raw_tool_output, triple, prefixes, func_dict, + verbose): + target_handlers = { + 'x86_64': (scrub_asm_x86, ASM_FUNCTION_X86_RE), + 'i686': (scrub_asm_x86, ASM_FUNCTION_X86_RE), + 'x86': (scrub_asm_x86, ASM_FUNCTION_X86_RE), + 'i386': (scrub_asm_x86, ASM_FUNCTION_X86_RE), + 'arm-eabi': (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_RE), + 'powerpc64le': (scrub_asm_powerpc64le, ASM_FUNCTION_PPC_RE), + } + handlers = None + for prefix, s in target_handlers.items(): + if triple.startswith(prefix): + handlers = s + break + else: + raise KeyError('Triple %r is not supported' % (triple)) + + scrubber, function_re = handlers for m in function_re.finditer(raw_tool_output): if not m: continue func = m.group('func') - if is_arm: - scrubbed_body = scrub_asm_arm(m.group('body')) - else: - scrubbed_body = scrub_asm_x86(m.group('body')) + scrubbed_body = scrubber(m.group('body')) if func.startswith('stress'): # We only use the last line of the function body for stress tests. scrubbed_body = '\n'.join(scrubbed_body.splitlines()[-1:]) @@ -120,9 +156,10 @@ func_dict[prefix][func] = scrubbed_body -def add_checks(output_lines, prefix_list, func_dict, func_name): +def add_checks(output_lines, run_list, func_dict, func_name): printed_prefixes = [] - for checkprefixes, _ in prefix_list: + for p in run_list: + checkprefixes = p[0] for checkprefix in checkprefixes: if checkprefix in printed_prefixes: break @@ -178,6 +215,13 @@ with open(test) as f: input_lines = [l.rstrip() for l in f] + triple_in_ir = None + for l in input_lines: + m = TRIPLE_IR_RE.match(l) + if m: + triple_in_ir = m.groups()[0] + break + run_lines = [m.group(1) for m in [RUN_LINE_RE.match(l) for l in input_lines] if m] if args.verbose: @@ -185,10 +229,16 @@ for l in run_lines: print >>sys.stderr, ' RUN: ' + l - prefix_list = [] + run_list = [] for l in run_lines: commands = [cmd.strip() for cmd in l.split('|', 1)] llc_cmd = commands[0] + + triple_in_cmd = None + m = TRIPLE_ARG_RE.search(llc_cmd) + if m: + triple_in_cmd = m.groups()[0] + filecheck_cmd = '' if len(commands) > 1: filecheck_cmd = commands[1] @@ -210,24 +260,29 @@ # FIXME: We should use multiple check prefixes to common check lines. For # now, we just ignore all but the last. - prefix_list.append((check_prefixes, llc_cmd_args)) + run_list.append((check_prefixes, llc_cmd_args, triple_in_cmd)) func_dict = {} - for prefixes, _ in prefix_list: + for p in run_list: + prefixes = p[0] for prefix in prefixes: func_dict.update({prefix: dict()}) - for prefixes, llc_args in prefix_list: + for prefixes, llc_args, triple_in_cmd in run_list: if args.verbose: print >>sys.stderr, 'Extracted LLC cmd: llc ' + llc_args print >>sys.stderr, 'Extracted FileCheck prefixes: ' + str(prefixes) raw_tool_output = llc(args, llc_args, test) - build_function_body_dictionary(raw_tool_output, prefixes, func_dict, args.verbose) + if not (triple_in_cmd or triple_in_ir): + print >>sys.stderr, "Cannot find a triple. Assume 'x86'" + + build_function_body_dictionary(raw_tool_output, + triple_in_cmd or triple_in_ir or 'x86', prefixes, func_dict, args.verbose) is_in_function = False is_in_function_start = False func_name = None - prefix_set = set([prefix for prefixes, _ in prefix_list for prefix in prefixes]) + prefix_set = set([prefix for p in run_list for prefix in p[0]]) if args.verbose: print >>sys.stderr, 'Rewriting FileCheck prefixes: %s' % (prefix_set,) output_lines = [] @@ -244,7 +299,7 @@ continue # Print out the various check lines here. - output_lines = add_checks(output_lines, prefix_list, func_dict, func_name) + output_lines = add_checks(output_lines, run_list, func_dict, func_name) is_in_function_start = False if is_in_function: